下划线的这种用法称为匿名函数的占位符语法:
这样的表达式表示一个匿名函数,其中随后出现的下划线表示连续的参数。
请注意,每个下划线指的是不同的参数,例如
_ + _
扩展到
(x1, x2) => x1 + x2
表达式_ + _
也使用无点语法,而不是
_.+(_)
例如
List("Steve", "Tom", "John", "Bob").reduce((x1: String, x2: String) => x1.+(x2)) // : String = "SteveTomJohnBob"
List("Steve", "Tom", "John", "Bob").reduce((x1, x2) => x1.+(x2)) // : String = "SteveTomJohnBob"
List("Steve", "Tom", "John", "Bob").reduce(_.+(_)) // : String = "SteveTomJohnBob"
List("Steve", "Tom", "John", "Bob").reduce(_ + _) // : String = "SteveTomJohnBob"
所以现在应该更清楚为什么表达_.compareTo(_) < 0
有效
List("Steve", "Tom", "John", "Bob").sortWith(_.compareTo(_) < 0) // : List[String] = List("Bob", "John", "Steve", "Tom")
List("Steve", "Tom", "John", "Bob").sortWith((x1, x2) => x1.compareTo(x2) < 0) // : List[String] = List("Bob", "John", "Steve", "Tom")
另一种看待这一点的方式让我们对含糖的表达式进行类型归因
scala> (_.compareTo(_) < 0): ((String, String) => Boolean)
val res0: (String, String) => Boolean = $Lambda$7865/418832725@18987bf5