在 Eclipse 工作表(2.10.1)中试过这个:
def a = { println("In a"); 3 } //> a: => Int
def b() = { println("In b"); 3 } //> b: ()Int
val c = () => { println("In c"); 3 } //> c : () => Int = <function0>
def test_type(x: => Int) = x //> test_type: (x: => Int)Int
test_type(a) //> In a
//| res0: Int = 3
b() //> In b
//| res1: Int = 3
c() //> In c
//| res2: Int = 3
test_type(b) //> In b
//| res3: Int = 3
// test_type(c) *** Doesn't compile
我肯定错过了一些东西。a
和b
和有什么区别c
?在我看来,这a
是(统一访问原则?)的“按名称”替代品,val a = 3
所以我不能打电话a()
,但为什么b
和c
有不同的类型?我也可以b
在没有括号的情况下调用(b
即将被评估为结果)以及a
,并且b
在调用时将转换为“按名称” test_type
,但c
不会和c
没有参数将被评估为函数本身(这看起来很合理)。
还有一个问题,Martin Odersky 在他的在线课程中说,如果我做对了,任何匿名函数() => 3
都可以替换为{ def f() = 3; f }
,但是这两个表达式有不同的类型和评估规则,首先将评估为一个函数,其次是函数结果,例如:
val f2 = { def f() = 3; f } //> f2 : Int = 3