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

时间:2014-08-24 16:08:44

标签: scala callbyname

以下代码可以编译:

def hello[T](f: => T) = f
hello(() => 12)

但不是:

def hello(f: => Int) = f
hello(() => 12)

报告错误:

<console>:9: error: type mismatch;
 found   : () => Int
 required: Int
                  hello(() => 12)

为什么?

2 个答案:

答案 0 :(得分: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>

你可以这么称呼:

scala> res1()
res2: Int = 12

第二种情况是你将一个函数从Unit传递给Int而不是Int(它返回一个Int但它不是Int })。

f作为名称参数调用传递的事实在这里没有任何区别:

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)

不要将此问题与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>

现在它在两种情况下进行编译,因为f是第一种情况下从UnitT的函数(其中T当然可以是Int在第二种情况下,fUnitInt的函数,您可以将() => 12作为参数传递。

答案 1 :(得分:0)

这仅仅是因为=> T() => T不一样......

=> T是按名称调用的,意思是

def hello(f: => Int) = f

应该像这样调用:

hello(12)

def hello[T](f: => T) = f() => 12合作的原因是因为您在T&#39}点上放置了Function0[Int],这与{{1}不同}

要使Int语法按预期工作,请考虑这样做:

() =>

现在你的函数期望 def hello(f: () => Int) = f // can also be written as: def hello(f: Function0[Int]) = f ,之前它没有,Function0将按预期工作