scala - 与下划线一起使用时,部分函数应用程序过早地运行代码块

标签 scala currying partialfunction eta-expansion

鉴于:

def save(f: => Any)(run:Boolean) { if (run) { println("running f"); f } else println("not running f") } 

我可以这样称呼它:
save("test")(true) -> running f
save("test")(false) -> not running f
save(throw new RuntimeException("boom!"))(false) -> not running f
save(throw new RuntimeException("boom!"))(true) -> running f and then exception thrown

这是部分应用的奇怪行为:
save(throw new RuntimeException("boom!"))(_) -> (Boolean) => Unit = <function1> //as expected
save(throw new RuntimeException("boom!")) _ -> exception thrown

代码块会立即被评估,而不是作为函数传入。以上2种说法有什么区别?

最佳答案

第一个案例 ,

save(throw new RuntimeException("boom!")) _ 

根据"Scala Reference" (第 6.7 节),使用尾随下划线代替参数列表,并将表达式转换为
val f: (Boolean) => Unit = save(throw new RuntimeException("boom!"))
def save 的第一个参数在哪里立即被评估。

The expression e _ is well-formed if e is of method type or if e is a call-by-name parameter. If e is a method with parameters, e _ represents e converted to a function type by eta expansion (§6.26.5). If e is a parameterless method or call-by-name parameter of type =>T , e _ represents the function of type () => T , which evaluates e when it is applied to the empty parameterlist ().



为了使事情按您的预期工作,需要进行一些修改:
scala> def save(f:() => Any)(run:Boolean) { if (run) { println("running f"); f() } else println("not running f") }
save: (f: () => Any)(run: Boolean)Unit

scala> val f = save(() => throw new RuntimeException("boom!")) _
f: (Boolean) => Unit = <function1>

scala> f(true)
running f
java.lang.RuntimeException: boom!
        at $anonfun$1.apply(<console>:6)

第二种情况 ,
save(throw new RuntimeException("boom!"))(_)

根据"Scala Reference" (第 6.23 节),当占位符用作参数的替换时,表达式将转换为
val f: (Boolean) => Unit = save(throw new RuntimeException("boom!"))(_)

关于scala - 与下划线一起使用时,部分函数应用程序过早地运行代码块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4918362/

相关文章:

java - 交叉口在 apache Spark 中不起作用

scala - scala 方法中变量参数的默认值

python - 在 python toolz 中柯里化(Currying) merge_with

javascript - 默认参数和柯里化(Currying) : Python vs. Javascript

Haskell,是否有可能创建一个可以 curry 任意数量的元组元素的 curry 函数

scala - 如何将一个偏函数转换为另一个偏函数?

scala - 如何在 Galing 中引用 CSV Feeder 中的变量?

scala - 在 Sbt 中包含 Spark 包

scala - Scala 中的魔术 PartialFunction