加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 关于call-by-name和0-arity函数之间差异的一些问题

发布时间:2020-12-16 09:25:11 所属栏目:安全 来源:网络整理
导读:这里有一些讨论,但我有一些具体的问题,我无法找到答案.因此,通过按名称呼叫,我的意思是= T型,并且通过0-arity函数我的意思是()= ? 我理解(我认为)概念上的差异,但可能我错过了一些东西,因为我仍然有很多问题: 为什么我们总是使用= T的概念,如果我们总能使用
这里有一些讨论,但我有一些具体的问题,我无法找到答案.因此,通过按名称呼叫,我的意思是=> T型,并且通过0-arity函数我的意思是()=> ?

我理解(我认为)概念上的差异,但可能我错过了一些东西,因为我仍然有很多问题:

>为什么我们总是使用=> T的概念,如果我们总能使用()=> T’
>每个都有任何语法/功能限制吗?现在我发现只有=>不能用作类字段.这是唯一的限制吗?
>两者的生成代码是否始终相同?
>我应该总是喜欢=> T?为什么?
>调用=> T类型是否正确?它看起来像它在scala中没有任何类型表示.

解决方法

1)使用它更方便,特别是在DSL中:

def printAndGet[T](f: => T) = {
  val res = f
  println(res + " printed") 
  res
}

scala> :paste
// Entering paste mode (ctrl-D to finish)

val k = printAndGet {
  val a = 5
  5 * a 
}

// Exiting paste mode,now interpreting.

25 printed
k: Int = 25

2)=> T只能是方法或函数的参数.实际上=> T和()=> T不可互换:

scala> def aaa(f: => String) = f
aaa: (f: => String)String

scala> val a: Function1[() => String,String] = aaa _
<console>:8: error: type mismatch;
 found   : (=> String) => String
 required: (() => String) => String
       val a: Function1[() => String,String] = aaa _
                                                ^

感谢@ som-snytt,发现这个:

scala> object O { def f(i: Int) = i; def f(i: => Int) = i + 1 }
defined object O

scala> O.f(5)
res12: Int = 5

scala> O.f(5: (=> Int))
<console>:1: error: no by-name parameter type allowed here
       O.f(5: (=> Int))
           ^

即使这个应该工作,如果它编译 – 但它没有(scala 2.11.2,2.11.5 REPL只是崩溃):

scala> val k: (=> Int) => Int = O.f _
k: (=> Int) => Int = <function1>

scala> k(5) //should be 6
res18: Int = 5 //WTF?

最后一个看起来像个bug

3)不完全是,如果你想要相同,只需转换=> T into()=> T:

scala> def aaa(f: => String) = {f _}
aaa: (f: => String)() => String

字节码也可能不同.例如,编译器更可能内联代码来自=> T没有为它生成lambda.所以,关键的区别是()=> T实际上是一个对象(一等公民),=> T不是.

4)参见1,但有时您可能需要确保用户知道计算可能会延迟 – ()=> T更好.

5)它是类型签名的一部分,只需看看以下的eta扩展:

scala> def aaa(f: => String) = {f}
aaa: (f: => String)String

scala> aaa _ //convert method into a function
res7: (=> String) => String = <function1>

scala> val a: ( => String) =>  String = aaa _
a: (=> String) => String = <function1>

但是scala不承认它是独立类型:

scala> val a: Function1[( => String),String] = aaa _
<console>:1: error: no by-name parameter type allowed here
       val a: Function1[( => String),String] = aaa _
                          ^

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读