我有一些测试结果我无法解释。
第一个测试对包含 4 个元素的列表进行过滤、映射和归约:
{
val counter = new AtomicInteger(0)
val l = List(1, 2, 3, 4)
val filtered = l.filter{ i =>
counter.incrementAndGet()
true
}
val mapped = filtered.map{ i =>
counter.incrementAndGet()
i*2
}
val reduced = mapped.reduce{ (a, b) =>
counter.incrementAndGet()
a+b
}
println("counted " + counter.get + " and result is " + reduced)
assert(20 == reduced)
assert(11 == counter.get)
}
计数器按我的预期增加了 11 倍:过滤期间每个元素一次,映射期间每个元素一次,以及 3 次以将 4 个元素相加。
使用通配符会改变结果:
{
val counter = new AtomicInteger(0)
val l = List(1, 2, 3, 4)
val filtered = l.filter{
counter.incrementAndGet()
_ > 0
}
val mapped = filtered.map{
counter.incrementAndGet()
_*2
}
val reduced = mapped.reduce{ (a, b) =>
counter.incrementAndGet()
a+b
}
println("counted " + counter.get + " and result is " + reduced)
assert(20 == reduced)
assert(5 == counter.get)
}
我不知道如何在 reduce 中使用通配符(代码无法编译),但现在,计数器只增加了 5 次!!
那么,问题 #1:为什么通配符会改变调用计数器的次数,以及它是如何工作的?
然后是我的第二个相关问题。我对视图的理解是它们会懒惰地执行传递给单子方法的函数,但是下面的代码没有显示出来。
{
val counter = new AtomicInteger(0)
val l = Seq(1, 2, 3, 4).view
val filtered = l.filter{
counter.incrementAndGet()
_ > 0
}
println("after filter: " + counter.get)
val mapped = filtered.map{
counter.incrementAndGet()
_*2
}
println("after map: " + counter.get)
val reduced = mapped.reduce{ (a, b) =>
counter.incrementAndGet()
a+b
}
println("after reduce: " + counter.get)
println("counted " + counter.get + " and result is " + reduced)
assert(20 == reduced)
assert(5 == counter.get)
}
输出是:
after filter: 1
after map: 2
after reduce: 5
counted 5 and result is 20
问题 #2:为什么函数会立即执行?
我正在使用 Scala 2.10