给定:
def higherOrderCallByName(f: => Int => Int, x: Int): Int = f(x)
def higherOrderCallByValue(f: Int => Int, x: Int): Int = f(x)
在什么情况下,对函数参数使用调用名称是惯用/正确的,即higherOrderCallByName
中的f
?
最佳答案
澄清一下,在按值调用中,参数的值在传递给函数之前确定,而在按名称调用中参数的计算被推迟到在函数内部使用时为止。
我同意 m-z 的观点,higherOrderCallByName
在传递的函数可能是昂贵的调用的情况下完全有效。
我能想到的另一个场景是,如果传递的函数有一些副作用,那么按名称参数的行为将与按值参数不同。我修改了您的示例来演示这一点:
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.
当遇到 f(x)
时,内部 higherOrderCallByName
会发生副作用。现在想象一下在 higherOrderCallByName
内多次执行 f(x)
的场景。显然,这会对您的应用程序产生很大影响。
关于scala - 带名称调用的高阶函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38236850/