功能后下划线?

Lif*_*ang 5 scala

特定

scala> def method(x: Int) = x
method: (x: Int)Int

scala> val func = (x: Int) => x
func: Int => Int = <function1>
Run Code Online (Sandbox Code Playgroud)

请考虑以下代码:

scala> method _
res0: Int => Int = <function1>

scala> func(_)
res1: Int => Int = <function1>

scala> func _
res2: () => Int => Int = <function0>
Run Code Online (Sandbox Code Playgroud)

我可以理解,这res0是eta扩展,res1相当于lambda函数(x) => func(x).但我无法弄清楚输出res2.谁有人可以帮我解释一下?

Ale*_*nov 7

这实际上有点棘手.首先,让我们看看REPL之外会发生什么:

当局部变量时它不起作用func:

object Main extends App {
  def foo() = {
    val f = (_: Int) + 1
    f _
  }

  println(foo())
}

[error] /tmp/rendereraEZGWf9f1Q/src/main/scala/test.scala:8: _ must follow method; cannot follow Int => Int
[error]     f _
[error]     ^
Run Code Online (Sandbox Code Playgroud)

但如果你把它放在外面def foo,它会编译:

object Main extends App {
  val f = (_: Int) + 1
  val f1 = f _

  println(f1)
}
Run Code Online (Sandbox Code Playgroud)

因为f既是字段Main方法不使用参数,它返回这个字段的值.

最后一块是REPL将每一行包装成一个对象(因为Scala不允许代码出现在trait/class/object之外),所以

scala> val func = (x: Int) => x
func: Int => Int = <function1>    
Run Code Online (Sandbox Code Playgroud)

真的很像

object Line1 {
  val func = (x: Int) => x
}
import Line1._
// print result
Run Code Online (Sandbox Code Playgroud)

所以func在下一行指的是Line1.func哪种方法,因此可以进行eta扩展.