我认为这里发生的是Scala编译器中的两个独立机制在一起工作:
价值抛弃
这基本上只是一种避免显式写入的方法
()
这个
Unit
单元
是预期的类型。就像在
while
循环,a
单元
返回方法,a
for(a <- list){ ... }
表达等。
def foo: Unit = 42
def foo: Unit = { 42; () }
Eta扩展
这就是
方法
在Scala中,转换为
功能
scala.FunctionN
班可以将函数作为值传递(因为它们是值),但不能将方法作为值传递。
因此,编译器基本上执行以下转换:
def foo(i: Int): Int = i
def bar(f: Int => Int) = f
bar(foo)
~~~>
bar( (x1: Int) => foo(x1) )
把两者结合起来
所以当你有了这个代码:
def foo(i: Int): Int = i
def bar(f: Int => Unit) = f
bar(foo)
编译器将首先使用eta扩展进行转换
foo
bar( (x1: Int) => foo(x1) )
然后它会看到
foo(x1)
是类型的表达式
Int
而类型的表达式
单元
预计在那里。因此它将应用值丢弃。
bar( (x1: Int) => { foo(x1); () } )
您可以检查此“问题”仅在将方法转换为函数时发生:
scala> def bar(f: Int => Unit) = f
bar: (f: Int => Unit)Int => Unit
scala> val foo = (i: Int) => i
foo: Int => Int = <function1>
scala> bar(foo)
<console>:14: error: type mismatch;
found : Int => Int
required: Int => Unit
bar(foo)
^