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 */ }
答案 0 :(得分:2)
地图如何处理两者?
它能够处理两者,因为编译器通过map
上的method value为println
创建了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
返回Unit
,Array.foreach
更适合此处:
Array("hi","there").foreach(println)