Scala映射方法语法

Scala映射方法语法,scala,syntax,Scala,Syntax,下面的代码从做矩阵点积开始 我不明白花括号之间的语法 为什么使用花括号,而不是常规方法括号 这不是匿名方法吗 什么是._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(_ + _) 花括号表示类型为Tuple2[Dou

下面的代码从做矩阵点积开始

我不明白花括号之间的语法

  • 为什么使用花括号,而不是常规方法括号
  • 这不是匿名方法吗
  • 什么是._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(_ + _)

花括号表示类型为
Tuple2[Double,Double]=>Double
的匿名函数。参数的本地名称为
t
,因此
t
是两个双元组。
t.\u 1
指第一项,而
t.\u 2
指第二项


因此,
map
生成两个向量分量的元素乘积列表,并且
reduceLeft
对这些乘积求和以计算点积。

在这种特殊情况下,花括号与普通的旧语法相比没有优势,但一般来说,使用花括号的好处在于,它们允许您在
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 )

._1、._2提供对第一、第二。。。N元组的N元素,正如Lee所说。

在这个问题中,你可以找到括号{}和括号()之间差异的很好答案:

对于_1,_2,请参见

是的,
t:(Double,Double)=>t._1*t._2
是一个匿名函数(实际上不是一个方法)

  • 为什么使用花括号,而不是常规方法括号
当参数是匿名函数时,有些人更喜欢使用大括号。首先,大括号支持模式匹配匿名函数,而括号则不支持。在这个特殊的例子中,不需要花括号

下面是一个需要大括号的示例(因为
大小写
模式匹配):

请注意,上述函数与问题中的函数以稍微不同的方式完成相同的任务

  • t
    是匿名方法吗
不,它是一个参数。就像
v1
v2
dotProd
的参数一样,
t
是传递给
map
的匿名函数的参数

  • 什么是
    \u 1
    \u 2
t
上的方法。参数
t
被定义为一个元组(特别是
Tuple2[Double,Double]
,可以写成
(Double,Double)
),元组允许您使用如下方法提取元组的每个成员:
\u1
\u2
\u3
,等等

当然,
Tuple2
只有
\u1
\u2
。请注意,由于受到其他函数语言的影响,第一个参数是
\u 1
,而不是
\u 0


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

上面的和这个
列表(1,2,3)有什么区别。map(x=>x+1)
@Nabegh在这种情况下,没有区别。大括号中不能有多个参数。呃,
t
是一个参数,不是匿名函数。@DanielC.Sobral是的,当然你是对的,我的意思是整个构造都是匿名函数。
\u 1
\u 2
真的是
Tuple2
的方法吗?我知道它们是字段(如
TupleN
中的
N
字段从
\u1
\un
,每个字段都是某种类型的
Ti
@TamoghnaChowdhury当然,它们是方法。Scala几乎通过方法访问所有字段,除非它们声明为
私有[这]
.Oops.你完全正确。透明属性确实会让习惯于Java中显式访问器/变异器的人感到困惑,比如我:P。不过,谢谢你再次提醒我。。。
def dotProd(v1:Row, v2:Row) = 
    v1.zip(v2).map{ case (a, b) => a * b }.reduceLeft(_ + _)