Scala iterator: "you can never use an iterator after calling a method on it" - why?

The Scala Iterator [T] documentation here says the following:

It is especially important to note that, unless otherwise indicated, you should never use an iterator after calling a method on it. The two most important exceptions are also the only abstract methods: next and hasNext .

They also provide a concrete example of safe and unsafe use:

 def f[A](it: Iterator[A]) = { if (it.hasNext) { // Safe to reuse "it" after "hasNext" it.next // Safe to reuse "it" after "next" val remainder = it.drop(2) // it is *not* safe to use "it" again after this line! remainder.take(2) // it is *not* safe to use "remainder" after this line! } else it } 

Unfortunately, I am not following the idea of ​​insecurity here. Can anyone shed some light for me here?

+4
source share
2 answers

val remainder = it.drop(2) can be implemented like this: it creates a new wrapper iterator that stores a reference to the original it operator and advances it twice, so the next time you call remainder.next , you get the third element. But if you then call it.next between them, remainder.next will return the 4th element ...

So, you have the remainder and it links that you might need to call next and do the same side effect that is not supported by the implementation.

+4
source

Here is a concrete example:

 def eleventh[A](xs: Iterator[A]) = { xs.take(10).toList xs.next } 

We can try:

 scala> eleventh((1 to 100).toList.toIterator) res0: Int = 11 scala> eleventh((1 to 100).toStream.toIterator) res1: Int = 11 scala> eleventh(Stream.from(1).toIterator) res2: Int = 11 

Looks nice. But then:

 scala> eleventh((1 to 100).toIterator) res3: Int = 1 

Now (1 to 100).toIterator is of the same type as (1 to 100).toList.toIterator , but they behave very differently here - we see that implementation details flow from the API. This is very bad, and it is the direct result of mixing purely functional combinators like take with an inherently imperative and mutable concept such as an iterator.

+4
source

Source: https://habr.com/ru/post/1498745/


All Articles