Scala map方法语法

时间:2012-05-03 11:40:22

标签: scala syntax

以下代码http://www.scalaclass.com/book/export/html/1做矩阵点积。

我无法理解大括号之间的语法。

  • 为什么使用大括号,而不是常规方法括号?
  • 这是匿名方法吗?
  • 什么是._1和._2?

感谢。

type Row    = List[Double]
type Matrix = List[Row]

def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ t:(Double, Double) => t._1 * t._2 }.reduceLeft(_ + _)

4 个答案:

答案 0 :(得分:36)

  • 为什么使用花括号,而不是常规方法括号?

当参数是匿名函数时,有些人更喜欢使用花括号。首先,花括号启用模式匹配匿名函数,而括号不支持。在这个特定的例子中,不需要大括号。

以下是需要花括号的示例(由于case模式匹配):

def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ case (a, b) => a * b }.reduceLeft(_ + _)

请注意,上述功能与问题中的功能完全相同,只是略有不同。

  • t是匿名方法吗?

不,这是一个参数。就像v1v2dotProd的参数一样,t是传递给map的匿名函数的参数。

  • 什么是._1._2

t上的方法。参数t被定义为元组(具体地,Tuple2[Double, Double],可以写为(Double, Double)),元组允许您使用以下方法提取元组的每个成员:{ {1}},_1_2

_3当然只有Tuple2_1。请注意,由于其他函数语言的影响,第一个参数是_2,而不是_1

无论如何,_0方法会将zipRow)转换为List[Double]。方法List[(Double, Double)]采用一个函数将列表的元素(map元组)转换为其他元素。

答案 1 :(得分:19)

在这种特殊情况下,花括号与普通旧语法相比没有优势,但一般来说,使用花括号的好处是它们允许您在map ...内编写模式匹配表达式:

所以我可以重写这个

.map{ t:(Double, Double) => t._1 * t._2 }

进入这个

.map{ case(a: Double, b: Double) => a*b }

但这不会编译:

.map( case(a: Double, b: Double) => a*b )
正如Lee所说,

._ 1,._2提供了对N元组的第一,第二,...... N元素的访问。

答案 2 :(得分:5)

在这个问题中,你可以找到一个非常好的答案来解决大括号{}和括号()之间的差异:What is the formal difference in Scala between braces and parentheses, and when should they be used?

对于_1,_2,请参阅Meaning of _2 sign in scala language

是的,t:(Double, Double) => t._1 * t._2是一个匿名函数(实际上不是一个方法)。 Difference between method and function in Scala

答案 3 :(得分:1)

花括号表示一个类型为Tuple2[Double,Double] => Double的匿名函数。该参数被赋予本地名称t,因此t是两个双元组的元组。t._1表示第一个项目,t._2表示第二个项目。

因此map会生成两个向量组件的元素乘积列表,reduceLeft对这些乘积进行求和以计算点积。