将新的Iterable {}代码从Scala 2.7.7移植到2.8

Ale*_*ack 5 iterable scala scala-2.8

我看到了这个帖子:

Scala 2.8和Scala 2.7之间最大的区别是什么?

它似乎涵盖了一些变化,但似乎没有提到我遇到的第一个编译问题.有什么建议?

  • 类型参数的种类(Iterable [Any] with(A with Int)=> Any)不符合类GenericCompanion中类型参数(类型CC)的预期种类.Iterable [Any] with(A with Int)=> Any的类型参数与CC类型的预期参数不匹配:没有类型参数,但CC类型有一个
  • 对象创建不可能,因为特征中的方法迭代器IterableLike类型=> Iterator [java.io.File]未定义
  • 对象创建是不可能的,因为类型=> Iterator [V]的trait IterableLike中的方法迭代器未定义
  • 在trait中重写方法元素IterableLike of type => Iterator [java.io.File]; 方法元素需要`覆盖'修饰符
  • 在trait中重写方法元素IterableLike of type => Iterator [V]; 方法元素需要`覆盖'修饰符

这是有问题的代码:

/**
 * Filesystem walker.
 * <p>
 * Less magic version of: http://rosettacode.org/wiki/Walk_Directory_Tree#Scala
 */
object FsWalker {
  /**
   * Recursive iterator over all files (and directories) in given directory.
   */
  def walk(f: File): Iterable[File] = new Iterable[File] {
    def elements = {
      if (f.isDirectory()) {
        // recurse on our child files
        f.listFiles.elements.flatMap(child => FsWalker.walk(child).elements)
      } else {
        // just return given file wrapped in Iterator
        Seq(f).elements
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Ran*_*ulz 7

前者elements现在iterator.

您应该使用-Xmigration进行编译,以获取有关如何将代码从2.7移植到2.8的有用提示.


jsu*_*eth 5

这里的关键是确保将方法迭代器与Iterable一起使用.Scala 2.8.0也做了很多工作,以确保类型在集合调用中保持一致.

scala> val x = new Iterable[String] {
     | def iterator = List("HAI", "YOU", "GUYS").iterator
     | }
x: java.lang.Object with Iterable[String] = line18(HAI, YOU, GUYS)
Run Code Online (Sandbox Code Playgroud)

我还会考虑使用Stream而不是迭代器.迭代器方法将在调用迭代器方法时构造整个文件集.流可能是懒惰的.

scala> def files(f : File) : Stream[File] = {
     |   if(f.isDirectory) {                   
     |     f.listFiles.toStream.map(files).flatten
     |   } else Stream(f)
     | }
files: (f: java.io.File)Stream[java.io.File]

scala> files(new File("/home/jsuereth/projects/scala/scala"))
res1: Stream[java.io.File] = Stream(/home/jsuereth/projects/scala/scala/build/manmaker/classes/scala/man1/sbaz.class, ?)

scala> res1 take 10 foreach println
/home/jsuereth/projects/scala/scala/build/manmaker/classes/scala/man1/sbaz.class
/home/jsuereth/projects/scala/scala/build/manmaker/classes/scala/man1/scala$$anon$1.class
...
Run Code Online (Sandbox Code Playgroud)

或者,如果要在流中包含目录,请尝试以下操作:

scala> def files_with_dirs(f : File) : Stream[File] = {
     | if(f.isDirectory) Stream.cons(f, f.listFiles.toStream.map(files).flatten)
     | else Stream(f)
     | }
files_with_dirs: (f: java.io.File)Stream[java.io.File]
Run Code Online (Sandbox Code Playgroud)