正如我所理解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 = ...
不再打印任何内容。