以下代码可以编译:
def hello[T](f: => T) = f
hello(() => 12)
Run Code Online (Sandbox Code Playgroud)
但不是:
def hello(f: => Int) = f
hello(() => 12)
Run Code Online (Sandbox Code Playgroud)
哪个报告错误:
<console>:9: error: type mismatch;
found : () => Int
required: Int
hello(() => 12)
Run Code Online (Sandbox Code Playgroud)
为什么?
我会说,因为T可以是任何() => x,但Int不能是一个() => x.
在你的情况下,你() => 12作为参数传递,这是一个合法的行为,因为T没有约束,可以是任何东西,实际上这样做会返回一个部分应用函数:
scala> def hello[T](f: => T) = f
hello: [T](f: => T)T
scala> hello(()=>12)
res1: () => Int = <function0>
Run Code Online (Sandbox Code Playgroud)
你可以这么称呼:
scala> res1()
res2: Int = 12
Run Code Online (Sandbox Code Playgroud)
第二种情况,而不是你是从传递一个函数Unit来Int这不是Int(它返回一个Int,但它不是一个Int).
f通过name参数传递的事实在这里没有任何区别:
scala> def hello[T](f: T) = f
hello: [T](f: T)T
scala> hello(()=>12)
res11: () => Int = <function0>
scala> def hello(f: Int) = f
hello: (f: Int)Int
scala> hello(()=>12)
<console>:9: error: type mismatch;
found : () => Int
required: Int
hello(()=>12)
Run Code Online (Sandbox Code Playgroud)
不要混淆:f: => T用这个:f: () => T它们是不同的东西,要说清楚:
scala> def hello[T](f: () => T) = f
hello: [T](f: () => T)() => T
scala> hello(()=>12)
res13: () => Int = <function0>
scala> def hello(f: () => Int) = f
hello: (f: () => Int)() => Int
scala> hello(()=>12)
res14: () => Int = <function0>
Run Code Online (Sandbox Code Playgroud)
现在,在这两种情况下编译,因为f是一个函数从Unit到T在第一种情况下(其中,T当然可以是一个Int),并在第二种情况下f是从函数Unit到Int并可以通过() => 12作为参数.