昨天我在 SO: scala List map vs mapConserve 发现了 scala mapConserve
我的问题是,什么时候有人想要使用这种方法?提供的示例使用带有身份函数的mapConserve,但我看不到它的用例...
编辑:快速搜索 GitHub并找到了 816 个使用 mapConserve 的 Scala 代码块。其中许多(至少 3 页)都是这样的代码块:
def checkStackOverflow() = {
var xs: List[String] = Nil
for (i <- 0 until 250000)
xs = "X" :: xs
val lowers = xs.mapConserve(_.toLowerCase)
assert(xs.mapConserve(x => x) eq xs)
}
最佳答案
这个问题引起了我的兴趣,因此我浏览了 Scala 代码库并了解了 mapConserves()
实际用途。
在几个地方弹出的是:如果参数是部分函数,则可以轻松跟踪 map 操作是否进行了实际更改(通过简单的引用检查),就像 Erasure 中的示例一样。 :
def squashBoxed(tp: Type): Type = tp.dealiasWiden match {
case t @ RefinedType(parents, decls) =>
val parents1 = parents mapConserve squashBoxed
if (parents1 eq parents) tp
else RefinedType(parents1, decls)
// ...
如果没有执行实际的更改,那么代码可以防止随后运行某种昂贵的操作。
该用例与常规 map()
的替代方案是..
- ..更昂贵[1]:迭代两个列表并随后比较它们的元素
- ..非功能性:在传递给
map()
的部分函数中跟踪是否通过更改某种外部标志进行了更改 -> 副作用,不是纯粹的,不是功能性的方式事物;恕我直言,总的来说也很丑
[1] 当然,这在给定情况下是否重要取决于优化之前的可疑措施。一般来说,现在该方法似乎很少使用,这可能表明它通常并不重要。
关于Scala mapConserve 用例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39613567/