为什么`def hello [T](f:=> T)= f; hello(()=> 12)`是可编译的但是`def hello(f:=> Int)= f; 你好(()=> 12)`不是吗?

Fre*_*ind 1 scala callbyname

以下代码可以编译:

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)

为什么?

End*_*Neu 6

我会说,因为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)

第二种情况,而不是你是从传递一个函数UnitInt这不是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是一个函数从UnitT在第一种情况下(其中,T当然可以是一个Int),并在第二种情况下f是从函数UnitInt并可以通过() => 12作为参数.

  • "我可能错了" - 不,你是绝对正确的,这正是这里发生的事情. (2认同)