据我所知 call-by-name
方法的参数,相应的参数表达式在传递给方法时不会被计算,但只有在方法体中使用参数的值时(和if)。
但是,在下面的例子中,这只适用于前两个方法调用,但不适用于第三个方法调用,尽管它应该只是第二种情况的语法变体!?
为什么在第三个方法调用中计算参数表达式?
(我使用Scala 2.11.7测试了这段代码)
class Node(x: => Int)
class Foo {
def :: (x: =>Int) = new Node(x) // a right-associative method
def !! (x: =>Int) = new Node(x) // a left-associative method
}
// Infix method call will not evaluate a call-by-name parameter:
val node = (new Foo) !! {println(1); 1}
println("Nothing evaluated up to here")
// Right-associative method call will not evaluate a call-by-name parameter:
val node1 = (new Foo).::({println(1); 1})
println("Nothing evaluated up to here")
// Infix and right-associative method call will evaluate a call-by-name parameter - why??
val node2 = {println(1); 1} ::(new Foo) // prints 1
println("1 has been evaluated now - why??")
只要提到它们,就会对名称参数进行评估。 规范说 右关联运算符方法调用的计算方式如下:
a op_: b
desugars:
{ val someFreshName = a; b.op_:(someFreshName) }
// ↑↑↑
// Eval happens here ↑↑↑
这是一个错误。那是一个旧的。
看到 SI-1980年 和PR #2852。
链接的pull请求在使用时添加了编译器警告 -Xlint
旗:
<console>:13: warning: by-name parameters will be evaluated eagerly when called as a right-associative infix operator. For more details, see SI-1980.
def :: (x: =>Int) = new Node(x) // a right-associative method
^
只要提到它们,就会对名称参数进行评估。 规范说 右关联运算符方法调用的计算方式如下:
a op_: b
desugars:
{ val someFreshName = a; b.op_:(someFreshName) }
// ↑↑↑
// Eval happens here ↑↑↑
这是一个错误。那是一个旧的。
看到 SI-1980年 和PR #2852。
链接的pull请求在使用时添加了编译器警告 -Xlint
旗:
<console>:13: warning: by-name parameters will be evaluated eagerly when called as a right-associative infix operator. For more details, see SI-1980.
def :: (x: =>Int) = new Node(x) // a right-associative method
^