답변:
간단히 말해서, 반복자는 상태를 유지하고 트래버 서블은 유지하지 않습니다.
A Traversable
에는 foreach
. 당신이 호출 할 때 foreach
, 컬렉션은 전달 기능을 그것을 유지하는 모든 요소를 하나씩 공급됩니다.
반면 에는를 반환하는 Iterable
추상 메서드 iterator
가 있습니다 Iterator
. 당신이 호출 할 수 next
온 Iterator
당신의 선택의 시점에서 다음의 요소를 얻을 수 있습니다. 그렇게 할 때까지 컬렉션의 위치와 다음 작업을 추적해야합니다.
Iterable
extends Traversable
, 그래서 나는 당신이 Traversable
s가 아닌 Iterable
s 를 의미한다고 생각합니다 .
Traversable
인터페이스를 준수하는 것은 상태를 유지할 필요가 없지만 인터페이스를 준수한다는 것을 의미 Iterator
합니다.
Traversable
이다들 Iterable
어떤 반복 상태를 유지하지 않습니다. 그것은 것 Iterator
생성에 의해 반환 된 Iterable
상태를 그대로 유지합니다.
불고 빨기의 차이로 생각하십시오.
Traversable
s foreach
또는 파생 메서드를 호출하면 한 번에 하나씩 해당 값을 함수에 불어 넣어 반복을 제어 할 수 있습니다.
으로 Iterator
에 의해 반환 Iterable
하지만, 당신은 다음 중 하나 자신에게 이동할 때 제어, 그것의 값을 빨아.
tl; dr Iterables
은 Traversables
상태 저장을 생성 할 수 있습니다.Iterators
우선, 그가 알 Iterable
의 subtrait됩니다 Traversable
.
둘째,
Traversable
foreach
다른 모든 것에서 사용되는 메서드를 구현해야합니다 .
Iterable
iterator
다른 모든 것에서 사용되는 메서드를 구현해야합니다 .
예를 들어, 상기의 구현 find
을위한 Traversable
용도 foreach
(이해하는 비아)과는 슬로우 BreakControl
충분한 요소가 발견 된 후 반복을 중지하는 예외.
trait TravserableLike {
def find(p: A => Boolean): Option[A] = {
var result: Option[A] = None
breakable {
for (x <- this)
if (p(x)) { result = Some(x); break }
}
result
}
}
반대로, Iterable
빼기는이 구현을 재정의하고를 호출합니다 find
.이 Iterator
경우 요소가 발견되면 반복이 중지됩니다.
trait Iterable {
override /*TraversableLike*/ def find(p: A => Boolean): Option[A] =
iterator.find(p)
}
trait Iterator {
def find(p: A => Boolean): Option[A] = {
var res: Option[A] = None
while (res.isEmpty && hasNext) {
val e = next()
if (p(e)) res = Some(e)
}
res
}
}
Traversable
반복을 위해 예외를 던지지 않는 것이 좋지만 .NET을 사용할 때 부분적으로 반복하는 유일한 방법 foreach
입니다.
하나의 관점 Iterable
에서는를 foreach
사용하여 쉽게 구현할 iterator
수 있지만 실제로를 iterator
사용하여 구현할 수 없기 때문에 더 까다 롭고 강력한 특성 foreach
입니다.
요약 Iterable
하면 stateful을 통해 반복을 일시 중지, 재개 또는 중지하는 방법을 제공합니다 Iterator
. 을 사용하면 Traversable
전부 또는 전혀 없습니다 (흐름 제어에 대한 예외는 제외).
대부분의 경우 중요하지 않으며 더 일반적인 인터페이스가 필요합니다. 그러나 반복에 대한보다 맞춤화 된 제어가 필요한 Iterator
경우 Iterable
.
Daniel의 대답은 좋은 것 같습니다. 내 말로 표현할 수 있는지 보자.
따라서 Iterable은 한 번에 하나씩 요소를 탐색하고 (next () 사용) 원하는대로 중지하고 이동할 수있는 반복자를 제공 할 수 있습니다. 이를 위해 반복자는 요소의 위치에 대한 내부 "포인터"를 유지해야합니다. 그러나 Traversable은 멈추지 않고 한 번에 모든 요소를 순회하는 foreach 방법을 제공합니다.
Range (1, 10)과 같은 것은 Traversable 상태로 정수 2 개만 있으면됩니다. 그러나 Iterable로서 Range (1, 10)는 상태에 대해 3 개의 정수를 사용해야하는 반복자를 제공하며, 그중 하나는 인덱스입니다.
Traversable도 foldLeft, foldRight를 제공한다는 점을 고려하면 foreach는 알려진 고정 된 순서로 요소를 탐색해야합니다. 따라서 Traversable에 대한 반복기를 구현할 수 있습니다. 예 : def iterator = toList.iterator
Traversable
에서 스칼라 2.13 (여전히를 위해 사용되지 않는 별칭으로 유지Iterable
2.14까지)