为什么`def hello [T](f:=> T)= f; hello(()=> 12)是可编译的,但`def hello(f:=> Int)= f; hello(()=> 12)`不是吗? [英] Why `def hello[T](f: => T) = f; hello(()=>12)` is compilable but `def hello(f: => Int) = f; hello(()=>12)` is not?
问题描述
以下代码可以编译:
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)
为什么?
我会说,因为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
作为参数传递.
Following code can be compiled:
def hello[T](f: => T) = f
hello(() => 12)
But following not:
def hello(f: => Int) = f
hello(() => 12)
Which reports error:
<console>:9: error: type mismatch;
found : () => Int
required: Int
hello(() => 12)
Why?
I would say because T
can be any () => x
, but Int
can't be a () => x
.
In your situation you are passing () => 12
as parameter which is a legal action because T
has no constrains and can be anything, in fact doing so returns a partial applied function:
scala> def hello[T](f: => T) = f
hello: [T](f: => T)T
scala> hello(()=>12)
res1: () => Int = <function0>
That you can call so:
scala> res1()
res2: Int = 12
The second case instead you are passing a function from Unit
to Int
which is not an Int
(it returns an Int
but it's not an Int
).
The fact that f
is passed as call by name parameter doesn't make any difference here:
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)
Don't confuse this: f: => T
with this: f: () => T
, they are different things, to make it clear:
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>
Now it compile in both cases because f
is a function from Unit
to T
in the first case (where T
can of course be an Int
) and in the second case f
is a function from Unit
to Int
and you can pass () => 12
as parameter.
这篇关于为什么`def hello [T](f:=> T)= f; hello(()=> 12)是可编译的,但`def hello(f:=> Int)= f; hello(()=> 12)`不是吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!