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

发布于 2024-09-13 18:53:31 字数 1332 浏览 2 评论 0原文

我看到了这个帖子:

什么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 中的方法迭代器 类型 =>迭代器[java.io.File]是 未定义的
  • 对象创建是不可能的,因为 特征 IterableLike 中的方法迭代器 类型 => Iterator[V] 未定义
  • 重写特征中的方法元素 IterableLike 类型 => 迭代器[java.io.File];方法 元素需要“override”修饰符
  • 来覆盖特征中的方法元素 IterableLike 类型 =>迭代器[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
      }
    }
  }
}

I saw this thread:

What are the biggest differences between Scala 2.8 and Scala 2.7?

It seems to cover some changes, but the first compile problems I've hit don't seem to be mentioned. Any suggestions?

  • kinds of the type arguments (Iterable[Any] with (A with Int) => Any) do not conform to the expected kinds of the type parameters (type CC) in class GenericCompanion. Iterable[Any] with (A with Int) => Any's type parameters do not match type CC's expected parameters: has no type parameters, but type CC has one
  • object creation impossible, since
    method iterator in trait IterableLike
    of type => Iterator[java.io.File] is
    not defined
  • object creation impossible, since
    method iterator in trait IterableLike
    of type => Iterator[V] is not defined
  • overriding method elements in trait
    IterableLike of type =>
    Iterator[java.io.File]; method
    elements needs `override' modifier
  • overriding method elements in trait
    IterableLike of type => Iterator[V];
    method elements needs `override'
    modifier

Here's the code in question:

/**
 * 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
      }
    }
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼泪也成诗 2024-09-20 18:53:32

以前的元素现在是迭代器

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

The former elements is now iterator.

You should compile with -Xmigration for helpful hints on how to port your code from 2.7 to 2.8.

醉殇 2024-09-20 18:53:32

这里的关键是确保将方法迭代器与 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)

我还会考虑使用 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
...

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

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]

The key here is to make sure you use the method iterator with an Iterable. Scala 2.8.0 also did a lot to ensure that types are consistent across collection calls.

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

I would also consider using a Stream instead of an iterator. The iterator approach will construct the entire set of files when calling the iterator method. A stream could be lazy.

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
...

Alternatively, if you want to include directories in the stream, try the following:

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]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文