假设:
def higherOrderCallByName(f: => Int => Int, x: Int): Int = f(x)
def higherOrderCallByValue(f: Int => Int, x: Int): Int = f(x)
在什么情况下,对于函数参数使用调用副名称是惯用的/正确的,即f
中的higherOrderCallByName
?
答案 0 :(得分:3)
为了澄清,在按值调用中,参数的值在传递给函数之前确定,而在按名称调用中参数的评估将推迟到函数内部使用。
我同意m-z,higherOrderCallByName
完全有效,其中传递的函数可能是一个昂贵的调用。
我能想到的另一个场景是,如果传递的函数有一些副作用,那么by-name参数的行为将与by-value参数不同。我修改了你的例子来证明这一点:
def higherOrderCallByName(f: => Int => Int, x: Int): Int = {
println("Inside by-name function.")
f(x)
}
def higherOrderCallByValue(f: Int => Int, x: Int): Int = {
println("Inside by-value function.")
f(x)
}
def funWithSideEffect() : (Int) => Int = {
println("Some side effect.") // some side-effect or some expensive call
x => x + 1 // returns function which increments param
}
现在,如果你打电话higherOrderCallByValue(funWithSideEffect(), 2)
输出将是:
Some side effect.
Inside by-value function.
如输出所示,在 higherOrderCallByValue
的身体执行之前会发生副作用。
higherOrderCallByName(funWithSideEffect(), 2)
的输出如下:
Inside by-name function.
Some side effect.
遇到higherOrderCallByName
时,在 f(x)
内发生副作用。现在想象一下在f(x)
内多次执行higherOrderCallByName
的场景。显然,它会对您的应用程序产生很大影响。