Scala:map的参数是函数OR函数调用

时间:2017-02-08 19:41:15

标签: scala mapper

Array("hi","there").map(println)
Array("hi","there").map(s => println(s))
Array("hi","there").map(println(_))

上述每个语句都会产生相同的输出,但在map的前2个参数中是一个函数对象,而在最后一个中它是函数调用。

地图如何处理这两种情况?

TraversableLike 类中地图的签名是这样的:

def map[B, That](f: scala.Function1[A, B])(implicit bf: scala.collection.generic.CanBuildFrom[Repr, B, That]) : That = { /* compiled code */ }

1 个答案:

答案 0 :(得分:2)

  

地图如何处理两者?

它能够处理两者,因为编译器通过map上的method valueprintln创建了eta-expansion。 Scala在方法和函数之间存在着区别,前者没有任何值,这使得编译器需要付出额外的努力才能使它工作。

eta-expansion之后的编译器实际发出:

Array("hi","there").map(s => println(s))

匹配你的第二个例子。实际代码更详细,但意思相同:

scala.this.Predef.refArrayOps[String](
  scala.Array.apply[String]("hi", "there")(
  (ClassTag.apply[String](classOf[java.lang.String]): scala.reflect.ClassTag[String])))
  .map[Unit, Any]({((x: Any) => scala.this.Predef.println(x))
  })(scala.this.Array.canBuildFrom[Unit]((ClassTag.Unit: scala.reflect.ClassTag[Unit])));

正如@slouc在评论中所说,使用占位符语法的第三个示例被归入s => println(s),这使它等同于您的第二个示例。

作为完整不那么重要的旁注,由于println返回UnitArray.foreach更适合此处:

Array("hi","there").foreach(println)