带下划线的scala传递函数产生的函数不是值

Ism*_*ush 3 functional-programming scala

嗨我正在编写任何可能的函数传递到map的变体,我最初的理解是它们都会产生相同的结果,但我发现第2,3行实际上产生了不同的输出,而第4行对我来说是一个谜

def g(v: Int) = List(v - 1, v, v + 1)
    val l = List(1, 2, 3, 4, 5)
    // map with some variations
    println(l.map { x => g(x) })
    println(l.map { (_: Int) => g(_) }) // line 2
    println(l.map { (_) => g(_) }) // line 3
    println(l.map { _ => }) // line 4
    println(l.map { g(_) })
    println(l.map { g })
Run Code Online (Sandbox Code Playgroud)

输出:

List(List(0, 1, 2), List(1, 2, 3), List(2, 3, 4), List(3, 4, 5), List(4, 5, 6))
List(<function1>, <function1>, <function1>, <function1>, <function1>)
List(<function1>, <function1>, <function1>, <function1>, <function1>)
List((), (), (), (), ())
List(List(0, 1, 2), List(1, 2, 3), List(2, 3, 4), List(3, 4, 5), List(4, 5, 6))
List(List(0, 1, 2), List(1, 2, 3), List(2, 3, 4), List(3, 4, 5), List(4, 5, 6))
Run Code Online (Sandbox Code Playgroud)

Mic*_*jac 6

这些都是将函数的应用程序传递g给以下每个元素的等效方法List:

l.map { x => g(x) }
l.map { g(_) }
l.map { g }

res17: List[List[Int]] = List(List(0, 1, 2), List(1, 2, 3), List(2, 3, 4), List(3, 4, 5), List(4, 5, 6))
Run Code Online (Sandbox Code Playgroud)

这些是将所有元素映射List到未应用函数的等效方法,如g:

l.map { (_: Int) => g(_) }
l.map { (_) => g(_) }
Run Code Online (Sandbox Code Playgroud)

也就是说,映射列表的每个元素实际上都是g.

scala> l.map { (_: Int) => g(_) }.head
res23: Int => List[Int] = <function1>
scala> res23(0)
res24: List[Int] = List(-1, 0, 1)
Run Code Online (Sandbox Code Playgroud)

实际上,这两者之间的唯一区别是括号和类型注释.它们都相当于:

l.map { _ => g(_) }
Run Code Online (Sandbox Code Playgroud)

以下只是映射的所有元素ListUnit:

l.map { _ => }
Run Code Online (Sandbox Code Playgroud)

  • 为了进一步说明,我想补充一点,2和3相当于`l.map {x =>(_:Int)=> g(_)}`,其中`x`只是被丢弃了. (2认同)