将新的 Iterable 代码从 Scala 2.7.7 移植到 2.8
Posted
技术标签:
【中文标题】将新的 Iterable 代码从 Scala 2.7.7 移植到 2.8【英文标题】:Porting new Iterable code from Scala 2.7.7 to 2.8将新的 Iterable 代码从 Scala 2.7.7 移植到 2.8 【发布时间】:2011-03-27 13:30:23 【问题描述】:我看到了这个帖子:
What are the biggest differences between Scala 2.8 and 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] 是 未定义 无法创建对象,因为 特征 IterableLike 中的方法迭代器 类型 => Iterator[V] 未定义 覆盖特征中的方法元素 IterableLike 类型 => 迭代器[java.io.File];方法 元素需要 `override' 修饰符 覆盖特征中的方法元素 IterableLike 类型 => 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
【问题讨论】:
提供了文件的导入和iterator
的全局替换elements
,您的代码编译。
【参考方案1】:
以前的elements
现在是iterator
。
您应该使用 -Xmigration 进行编译,以获得有关如何将代码从 2.7 移植到 2.8 的有用提示。
【讨论】:
谢谢,就是这样。我会试试 -Xmigration【参考方案2】:这里的关键是确保将方法迭代器与 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]
【讨论】:
以上是关于将新的 Iterable 代码从 Scala 2.7.7 移植到 2.8的主要内容,如果未能解决你的问题,请参考以下文章
如何为 scala Iterable、spark 数据集制作编码器
Scala Option[String] map 变成 Iterable
将 Scala Iterable[T] 转换为 Option[Iterable[S]],如果所有 T 都是 S 的实例,则填充?
Scala:无法将数组传递给需要 Seq 或 Iterable 的函数