以下代码可以编译:
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)
为什么?
答案 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
是第一种情况下从Unit
到T
的函数(其中T
当然可以是Int
在第二种情况下,f
是Unit
到Int
的函数,您可以将() => 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
将按预期工作