尽管Python生成器很酷,但尝试复制它们确实不是Scala中最好的方法。例如,以下代码可以完成所需的工作:
def classStream(clazz: Class[_]): Stream[Class[_]] = clazz match { case null => Stream.empty case _ => ( clazz #:: classStream(clazz.getSuperclass) #::: clazz.getInterfaces.toStream.flatMap(classStream) #::: Stream.empty )}在其中,流是延迟生成的,因此它不会处理任何元素,直到被询问为止,您可以通过运行以下命令进行验证:
def classStream(clazz: Class[_]): Stream[Class[_]] = clazz match { case null => Stream.empty case _ => ( clazz #:: { println(clazz.toString+": super"); classStream(clazz.getSuperclass) } #::: { println(clazz.toString+": interfaces"); clazz.getInterfaces.toStream.flatMap(classStream) } #::: Stream.empty )}结果可以被转换成
Iterator简单地通过调用
.iterator对所得
Stream:
def classIterator(clazz: Class[_]): Iterator[Class[_]] = classStream(clazz).iterator
使用的
foo定义
Stream将这样呈现:
scala> def foo(i: Int): Stream[Int] = i #:: (if (i > 0) foo(i - 1) else Stream.empty)foo: (i: Int)Stream[Int]scala> foo(5) foreach println543210
另一种选择是将各种迭代器串联起来,注意不要预先计算它们。这是一个示例,其中还包含调试消息以帮助跟踪执行:
def yieldClass(clazz: Class[_]): Iterator[Class[_]] = clazz match { case null => println("empty"); Iterator.empty case _ => def thisIterator = { println("self of "+clazz); Iterator(clazz) } def superIterator = { println("super of "+clazz); yieldClass(clazz.getSuperclass) } def interfacesIterator = { println("interfaces of "+clazz); clazz.getInterfaces.iterator flatMap yieldClass } thisIterator ++ superIterator ++ interfacesIterator}这非常接近您的代码。取而代之的是
sudoYield,我有了定义,然后按需要将它们串联起来。
因此,尽管这是一个无法解决的问题,但我只是认为您在这里树错了树。尝试在Scala中编写Python肯定是徒劳的。在实现相同目标的Scala习惯用法上加倍努力。



