为了能够从方法/类返回迭代器,我必须做什么?如何将这种特性添加到一个类中?
最佳答案
这两个答案得到了以下帖子的帮助,感谢@Dima。
让我们假设你有一个类链表。要求是打印列表中的所有元素。
trait LinkedList {
def nodeValue: Int
def tailList: LinkedList
}
class Node(val nodeValue: Int, val tailList: LinkedList) extends LinkedList
object Nil extends LinkedList {
def nodeValue = throw new IllegalAccessException("head of Nil")
def tailList = throw new IllegalAccessException("tail of Nil")
}
val singleLinkedList = new Node(1,Nil)
val chainedLinkedList = new Node(2,singleLinkedList)
print(chainedLinkedList)
A$A44$A$A44$Node@7b7a2c78res0: Unit = ()
现在让我们实现这个类的迭代器。
trait LinkedList extends Iterator[Int]{
def nodeValue: Int
def tailList: LinkedList
}
class Node(val nodeValue: Int, val tailList: LinkedList) extends LinkedList {
var ptr: LinkedList = this
//The following two are mandatory for extending Iterator
override def hasNext: Boolean = ptr match { case Nil => false; case _=> true}
override def next(): Int = {
val result = ptr.nodeValue
ptr = ptr.tailList
result
}
}
object Nil extends LinkedList {
def nodeValue = throw new IllegalAccessException("head of Nil")
def tailList = throw new IllegalAccessException("tail of Nil")
//The following two are mandatory for extending Iterator
override def hasNext: Boolean = false
override def next(): Int = throw new IllegalAccessException("next of Nil")
}
val singleLinkedList = new Node(1,Nil)
val chainedLinkedList = new Node(2,singleLinkedList)
//Printing this first Time
chainedLinkedList.foreach(println)
//Prints 2 1
//Printing second Time
chainedLinkedList.foreach(println)
//No output
在迭代器实现中,一旦 ptr 到达末尾,它就不能前进。可迭代的实现解决了这个问题。
trait LinkedList extends Iterable[Int]{
val nodeValue: Int
val tailList: LinkedList
override def toString(): String = this.mkString(" -> ")
}
class Node(val nodeValue: Int, val tailList: LinkedList) extends LinkedList {
override def iterator: Iterator[Int] = Iterator
.iterate(this: LinkedList)(_.tailList)
.takeWhile(_ != Nil)
.map(_.nodeValue)
}
object Nil extends LinkedList {
lazy val nodeValue= throw new IllegalAccessException("head of Nil")
lazy val tailList = throw new IllegalAccessException("tail of Nil")
override def iterator: Iterator[Int] = Iterator.empty
}
val singleLinkedList = new Node(1,Nil)
val chainedLinkedList = new Node(2,singleLinkedList)
//Printing this first Time
chainedLinkedList.foreach(println)
Output 2 -> 1
chainedLinkedList.foreach(println)
Output 2 -> 1
关于scala - 如何在 Scala 中返回迭代器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2135462/