使用以下语法定义启用了curring的函数时:
def sum(x: Int)(y: Int)(z: Int) = x + y + z
一个仍然需要后缀来的咖喱呼叫任何电话sum
用_
:
sum _
sum(3) _
sum(3)(2) _
否则编译器会抱怨。
所以我诉诸:
val sum = (x: Int) => (y: Int) => (z: Int) => x + y + z
没有的作品_
。
现在的问题是:为什么需要多参数列表版本_
才能吸引用户加入?为什么这两个版本的语义在所有情况下都不相同?
另外,是否以某种方式不鼓励使用后者?是否有任何警告?
这两种语义不同的原因是方法和功能不是同一件事。
方法是全fledges JVM方法,而函数值(即像类实例Function1
,Function2
等等)。
所以
def sum(x: Int)(y: Int)(z: Int) = x + y + z
和
val sum = (x: Int) => (y: Int) => (z: Int) => x + y + z
可能看起来一样,但是第一个是方法,第二个是方法 Function1[Int, Function1[Int, Function1[Int, Int]]]
当您尝试使用需要函数值的方法时,编译器会自动将其转换为函数(称为eta-expansion的过程)。
但是,在某些情况下,编译器不会自动对方法进行eta扩展,例如您公开的情况,其中您明确希望部分应用它。
使用_
触发eta扩展,因此将方法转换为函数,并且每个人都很高兴。
根据scala规范,您还可以注释期望的类型,在这种情况下,扩展将自动执行:
def sum(x: Int)(y: Int)(z: Int) = x + y + z
val sumFunction: Int => Int => Int => Int = sum
这就是为什么相同的原因
def sum(x: Int, y: Int) = x + y
List(1,2,3).reduce(sum)
有效,即我们传递了一个显式需要函数的方法。
这是关于Scala何时执行eta扩展的更深入讨论:https : //stackoverflow.com/a/2394063/846273
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句