ssa*_*anj 9 scala currying partialfunction eta-expansion
鉴于:
def save(f: => Any)(run:Boolean) { if (run) { println("running f"); f } else println("not running f") }
Run Code Online (Sandbox Code Playgroud)
我可以用它来调用它:
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
Run Code Online (Sandbox Code Playgroud)
这是部分应用的奇怪行为:
save(throw new RuntimeException("boom!"))(_) -> (Boolean) => Unit = <function1> //as expected
save(throw new RuntimeException("boom!")) _ -> exception thrown
Run Code Online (Sandbox Code Playgroud)
立即评估代码块而不作为函数传递.上述两个陈述有什么区别?
第一个案例,
\n\nsave(throw new RuntimeException("boom!")) _ \nRun Code Online (Sandbox Code Playgroud)\n\n根据“Scala Reference”(\xc2\xa76.7),使用尾随下划线代替参数列表,并将表达式转换为
\n\nval f: (Boolean) => Unit = save(throw new RuntimeException("boom!"))\nRun Code Online (Sandbox Code Playgroud)\n\n其中 的第一个参数def save立即被求值。
\n\n\n如果 e\n 是方法类型或者 e 是按名称调用参数,则表达式 e _ 格式良好。如果 e 是带参数的方法,则 e _ 表示通过 eta 扩展转换为函数类型 (\xc2\xa76.26.5)。如果 e 是类型为 =>T 的无参数方法或按名称调用参数,则 e _ 表示类型为 () => T 的函数,该函数在将 e 应用于\n 时对 e 求值\n n 空参数列表()。
\n
为了使事情按您的预期工作,需要进行一些修改:
\n\nscala> def save(f:() => Any)(run:Boolean) { if (run) { println("running f"); f() } else println("not running f") }\nsave: (f: () => Any)(run: Boolean)Unit\n\nscala> val f = save(() => throw new RuntimeException("boom!")) _\nf: (Boolean) => Unit = <function1>\n\nscala> f(true)\nrunning f\njava.lang.RuntimeException: boom!\n at $anonfun$1.apply(<console>:6)\nRun Code Online (Sandbox Code Playgroud)\n\n第二个案例,
\n\nsave(throw new RuntimeException("boom!"))(_)\nRun Code Online (Sandbox Code Playgroud)\n\n根据“Scala Reference” (\xc2\xa76.23),当占位符用作参数的替换时,表达式将转换为
\n\nval f: (Boolean) => Unit = save(throw new RuntimeException("boom!"))(_)\nRun Code Online (Sandbox Code Playgroud)\n