据我理解,方法的 call-by-name
参数在传递给方法时不会被求值,只有当(如果)该参数的值在方法体中被使用时才会被求值。
然而,在下面的例子中,尽管它应该仅是第二种情况的语法变化,但这仅适用于前两次方法调用,而不适用于第三次方法调用!?
为什么第三个方法调用中对参数表达式进行了求值?
(我使用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??")
2020年的更新:请注意,Scala 2.13不再显示这种令人烦恼的行为:val node2 = ...
不会再打印任何内容。