我玩了一些占位符并发现了一个奇怪的案例:
val integers = Seq(1, 2)
val f = (x:Int) => x + 1
integers.map((_, f(_)))
返回
Seq[(Int, Int => Int)] = List((1,<function1>), (2,<function1>))
我在期待
Seq[(Int, Int)] = List((1, 2), (2, 3))
如果我进行了以下更改,一切都按预期工作:
integers.map(i => (i, f(i)))
知道为什么在映射期间不应用函数f
吗?
答案 0 :(得分:5)
下划线仅代表传递的参数一次。因此,在integers.map((_, f(_)))
中,第一个_
是来自integers
的值,但第二个_
具有&#34;部分应用函数&#34;的独立含义。< / p>
如果您的匿名函数需要2个(或更多)参数,那么您可以使用2个(或更多)下划线,但每个下划线只传递一次。
答案 1 :(得分:3)
Scala编译器无法读懂您的想法,因此_
占位符语法仅在非常简单的表达式中有用。
在你的例子中:
integers.map((_, f(_)))
它将f(_)
评估为一个独立的子表达式,所以你最终会得到与此类似的东西:
x => (x, y => f(y))
即使编译器没有将f(_)
视为自己的子表达式,结果也不会与您想要的结果相同:
integers.map(i => (i, f(i)))
您希望将_
的两个实例视为相同的参数,而不是_
的工作方式。表达式中每次出现的_
始终被视为唯一参数。