单抽象方法转换考虑函数的确切规则是什么?在下面的代码中有两个非常相似的情况,一个是编译的,第二个不是,当用Scala 2.12.4编译时:
trait SAM {
def apply(a: Int, b: Int): Unit
}
def callSAM(sam: SAM): Unit = {
sam(0, 1)
}
def iAmSam(f: (Int, Int) => Unit) = {
def lf(a: Int, b: Int) = f(a, b)
callSAM(f) // does not work - error:
// type mismatch:
// found (Int, Int) => Unit,
// required SAM
callSAM(lf) // works. What is the difference?
callSAM(f(_, _)) // works (lambda)
callSAM((a, b) => f(a, b)) // works (lambda)
}
callSAM(lf)
的工作原因是什么,callSAM(f)
没有?我在Scala 2.12 release notes中找到了提及,其中说:
请注意,只有lambda表达式转换为SAM类型实例,而不是FunctionN类型的任意表达式
lf
对我来说看起来不像lambda表达式。在2.12.0之后规则是否放宽了?接受lf
后,为什么f
不是?
答案 0 :(得分:3)
f
只是一个对象,完全属于
FunctionN类型的任意表达式
lf
是方法的名称,当用作表达式时,它是lf _
的简写,后者又扩展为(x, y) => lf(x, y)
,这是一个lambda表达式。