具有呼叫副名的高阶函数?

时间:2016-07-07 02:46:13

标签: scala

假设:

def higherOrderCallByName(f: => Int => Int, x: Int): Int = f(x)
def higherOrderCallByValue(f: Int => Int, x: Int): Int = f(x)

在什么情况下,对于函数参数使用调用副名称是惯用的/正确的,即f中的higherOrderCallByName

1 个答案:

答案 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的场景。显然,它会对您的应用程序产生很大影响。