【问题标题】:Scala map method syntaxScala map 方法语法
【发布时间】:2012-05-12 22:09:09
【问题描述】:

下面的代码来自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(_ + _)

【问题讨论】:

    标签: scala syntax


    【解决方案1】:
    • 为什么使用大括号,而不是常规方法括号?

    当参数是匿名函数时,有些人更喜欢使用花括号。一方面,花括号启用模式匹配匿名函数,而括号则没有。在这个特定的示例中,不需要花括号。

    这是一个需要大括号的示例(因为 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_2_3

    当然,Tuple2 只有_1_2。注意第一个参数是_1,而不是_0,因为受其他函数式语言的影响。

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

    【讨论】:

    • ._1._2 真的是 Tuple2 的方法吗?我知道它们是字段(如TupleN 将有从_1_NN 字段,每个字段都是Ti 的某种类型。
    • @TamoghnaChowdhury 当然,它们是方法。 Scala 通过方法访问几乎所有字段,除非它们被声明为private [this]
    • 糟糕。你是绝对正确的。透明属性确实会让习惯于在 Java 中显式访问器/突变器的人感到困惑,比如我:P。不过谢谢你再次提醒我……
    【解决方案2】:

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

    【讨论】:

    • 大括号内不能有多个参数。
    【解决方案3】:

    大括号{}和括号()的区别可以在这个问题中找到一个很好的答案: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

    【讨论】:

    • Err,t 是参数,不是匿名函数。
    • @DanielC.Sobral 是的,你当然是对的,我的意思是整个构造是一个匿名函数。
    【解决方案4】:

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

    因此,map 会生成两个向量分量的元素乘积列表,reduceLeft 将这些乘积相加以计算点积。

    【讨论】:

    • 上面和这个List(1,2,3).map(x => x + 1)有什么区别@
    • @Nabegh 在这种情况下,没有区别。
    猜你喜欢
    • 2016-04-03
    • 1970-01-01
    • 2013-11-05
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多