Scala 关于“按名称调用”函数与“0-arity”函数区别的几个问题
这里有一些关于这方面的讨论,但我有一些具体的问题,我无法找到答案。所以,通过名称调用,我指的是Scala 关于“按名称调用”函数与“0-arity”函数区别的几个问题,scala,Scala,这里有一些关于这方面的讨论,但我有一些具体的问题,我无法找到答案。所以,通过名称调用,我指的是=>Ttype,通过0-arity函数,我指的是()=>T 我理解(我认为)概念上的差异,但可能我遗漏了一些东西,因为我还有很多问题: 如果我们总是可以使用()=>T,为什么我们会有=>T的概念呢 每种语言都有语法/功能限制吗?现在我发现只有=>不能用作类字段。这是唯一的限制吗 生成的代码是否总是相同的 我应该总是更喜欢=>T?为什么 调用=>Ta类型正确吗?在我看来,它在scala中没有任何类型表示
=>T
type,通过0-arity函数,我指的是()=>T
我理解(我认为)概念上的差异,但可能我遗漏了一些东西,因为我还有很多问题:
()=>T
,为什么我们会有=>T
的概念呢=>
不能用作类字段。这是唯一的限制吗=>T
?为什么=>T
a类型正确吗?在我看来,它在scala中没有任何类型表示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 _
^
字节码也可能不同。例如,编译器更可能从=>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>defaaa(f:=>String)={f}
aaa:(f:=>字符串)字符串
scala>aaa//convert方法为函数
res7:(=>String)=>String=
scala>vala:(=>String)=>String=aaa_
答:(=>字符串)=>字符串=
但是scala不认为它是独立类型:
scala> val a: Function1[( => String), String] = aaa _
<console>:1: error: no by-name parameter type allowed here
val a: Function1[( => String), String] = aaa _
^
scala>vala:Function1[(=>String),String]=aaa_
:1:错误:此处不允许按名称参数类型
val a:Function1[(=>String),String]=aaa_
^
考虑一下这个评论——关于#2,您不能使用按名称类型归属,因此对于重载的f(i:Int)
和f(i:=>Int)
,您不能f(0:=>Int)
。与你关于“独立”型的观点相似。1)我理解。我不明白为什么我们需要特殊的=>T
符号?我们总是可以使用()=>T
,并假设任何表达式都是()=>
类型,而不是=>T
。2)这似乎不是真的。我至少可以将其用作本地val:defaa(f:=>String)={val g=f;println(g)}
然后aa{println(“已处理”);“return val”}
。我想知道它还有什么其他用途be@Archeg2)您的本地val只有T
类型,而不是=>T
,无法生成干净的=>T
类型请参见我尝试调整重载分辨率的第一条注释。
scala> def aaa(f: => String) = {f _}
aaa: (f: => String)() => String
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> val a: Function1[( => String), String] = aaa _
<console>:1: error: no by-name parameter type allowed here
val a: Function1[( => String), String] = aaa _
^