scala - 带名称调用的高阶函数?

标签 scala

给定:

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/

相关文章:

scala - 使代码的和平不可变

python - 解释 Spark 中的聚合功能(使用 Python 和 Scala)

Scala 组合;共产法?

scala - 如何在Scala中定义泛型?

java - 在 Java/Scala 中重现 CouchDB 1.2.0 密码哈希函数

android - Android 上的 Scala : java. lang.NoSuchMethodError : java. lang.String.isEmpty

scala - 从案例类创建 DataFrame

java - 在键和值中转义 JSON 的双引号?

scala - 如何在 Scala 中使用 StringOps 的 fold 方法?

scala - 动态创建测试 sbt