Как я понял 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 = ...
больше ничего не печатает.