为什么`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?

查看:121
本文介绍了为什么`def hello [T](f:=> T)= f; hello(()=> 12)是可编译的,但`def hello(f:=> Int)= f; hello(()=> 12)`不是吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码可以编译:

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是从UnitT的函数(其中T当然可以是Int),在第二种情况下是fUnitInt的函数,您可以将() => 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:=&gt; T)= f; hello(()=&gt; 12)是可编译的,但`def hello(f:=&gt; Int)= f; hello(()=&gt; 12)`不是吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆