【发布时间】:2021-11-17 10:09:23
【问题描述】:
我正在将一个项目从 Scala 2.12.1 迁移到 2.13.6,发现 SeqView#flatMap 现在返回一个 View,它没有 distinct 方法。因此,我有一段代码不再编译:
val nodes = debts.view
.flatMap { case Debt(from, to, _) => List(from, to) }
.distinct
.map(name => (name, new Node(name)))
.toMap
有一种愚蠢的方法可以解决这个问题,将视图转换为 seq,然后再转换回视图:
val nodes = debts.view
.flatMap { case Debt(from, to, _) => List(from, to) }.toSeq.view
.distinct
.map(name => (name, new Node(name)))
.toMap
但是,这显然不是很好,因为它会强制收集视图,而且必须在类型之间来回切换也非常不雅。我找到了另一种解决方法,即使用LazyList:
val nodes = debts.to(LazyList)
.flatMap { case Debt(from, to, _) => List(from, to) }
.distinct
.map(name => (name, new Node(name)))
.toMap
现在这就是我想要的,它基本上表现得像一个 Java 流。当然,有些操作有 O(n) 的内存使用量,例如 distinct,但至少所有操作在流式传输之后,无需重构数据结构。
有了这个,我开始思考为什么我们应该需要一个视图,因为它们的功能远没有以前那么强大(即使我相信 2.13 已经修复了这个功能引入的一些其他问题)。我寻找答案并找到了提示,但没有发现足够全面的内容。以下是我的研究:
- Description of views in 2.13
- 堆栈溢出:What is the difference between List.view and LazyList?
- Another comparison on an external website
可能是我,但即使在阅读了这些参考资料后,我也没有发现使用视图有明显的好处,即使不是全部用例也是如此。还有比我更开明的人吗?
【问题讨论】:
-
这看起来像是一个疏忽。 SeqView#flatMap 应该返回一个 SeqView,就像 Seq#flatMap 返回一个 Seq。您应该在 GitHub 中打开一个错误
-
嗯,我认为这是因为与之前变得复杂的库相比,他们必须限制类型的精确度以简化库。我会考虑提交一个错误来看看!
-
关于错误报告,有点类似于:github.com/scala/bug/issues/11159
标签: scala