【问题标题】:Difference between these two function formats这两种函数格式的区别
【发布时间】:2015-08-14 16:21:56
【问题描述】:

我正在研究 spark,而不是 scala 专家。我有地图功能的两种变体。你能解释一下它们之间的区别吗?

第一个变体和已知格式。

第一个变种

val.map( (x,y) => x.size()) 

第二个变体 -> 这已应用于元组

val.map({case (x, y) => y.toString()});

val 的类型是RDD[(IntWritable, Text)]。当我尝试使用第一个函数时,它给出了如下错误。

类型不匹配; 发现:(org.apache.hadoop.io.IntWritable,org.apache.hadoop.io.Text)⇒单位 必需:((org.apache.hadoop.io.IntWritable, org.apache.hadoop.io.Text)) ⇒ 单位

当我添加额外的括号时,它说,

元组不能在方法或函数参数中直接解构。

【问题讨论】:

  • 第一个变体是两个参数的函数,第二个是一个参数的函数,应该是一个元组。

标签: scala apache-spark


【解决方案1】:

你说:

val的类型是RDD[(IntWritable, Text)]

所以它是一个以 IntWritableText 为组件的元组 2。

如果你说

val.map( (x,y) => x.size())

你所做的实际上是在传递一个Function2,这是一个带有两个参数的函数到map 函数。这永远不会编译,因为map 想要一个带有 one 参数的函数。您可以执行以下操作:

val.map((xy: (IntWritable, Text)) => xy._2.toString)

使用._2 获取作为xy 传入的元组的第二部分(类型注释不是必需的,但更清楚)。

现在是第二个变体(你可以省略外部括号):

val.map { case (x, y) => y.toString() }

这是用于创建 PartialFunction 的特殊 scala 语法,它立即匹配传入以访问 xy 部分的元组。这是可能的,因为PartialFunction 扩展自常规的Function1 类(Function1[A,B] 可以写成A => B),带有一个参数。

希望它更清楚:)

【讨论】:

    【解决方案2】:

    我在 repl 中试试这个:

    scala> val l = List(("firstname", "tom"), ("secondname", "kate"))
    l: List[(String, String)] = List((firstname,tom), (secondname,kate))
    
    scala> l.map((x, y) => x.size)
    <console>:9: error: missing parameter type
    Note: The expected type requires a one-argument function accepting a    2-Tuple.
      Consider a pattern matching anonymous function, `{ case (x, y) =>  ... }`
              l.map((x, y) => x.size)
    

    也许能给你一些启发。

    【讨论】:

      【解决方案3】:

      您的第一个示例是一个接受两个参数并返回一个字符串的函数。这与此示例类似:

      scala> val f = (x:Int,y:Int) => x + y
      f: (Int, Int) => Int = <function2>
      

      您可以看到f 的类型是(Int,Int) =&gt; Int(只是将其稍微更改为返回一个int 而不是一个字符串)。这意味着这是一个将两个 Int 作为参数并返回一个 Int 作为结果的函数。

      现在你的第二个例子是一个语法糖(一个快捷方式),用于编写如下内容:

      scala> val g = (k: (Int, Int)) => k match { case (x: Int, y: Int) => x + y }
      g: ((Int, Int)) => Int = <function1>
      

      您会看到函数g 的返回类型现在是((Int, Int)) =&gt; Int。您看得出来差别吗? g 的输入类型有两个括号。这表明g 接受一个参数,并且该参数必须是Tuple[Int,Int](或简称(Int,Int))。

      回到你的RDD,你有一个Tuple[IntWritable, Text]的集合,所以第二个函数可以工作,而第一个函数不能工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多