scala下划线参数不作为命名参数,在spark map中减少

roe*_*oee 1 lambda scala encoder apache-spark

我在火花映射函数中使用下划线参数或命名参数时看到了一些区别.

看看这段代码(在spark-shell中执行):

var ds = Seq(1,2,3).toDS()
ds.map(t => Array("something", "" + t)).collect // works cool
ds.map(Array("funk", "" + _)).collect // doesn't work
Run Code Online (Sandbox Code Playgroud)

我得到的非工作线的例外是:

错误:无法找到存储在数据集中的类型的编码器.导入spark.implicits支持原始类型(Int,String等)和产品类型(case类).在将来的版本中将添加对序列化其他类型的支持.

Yuv*_*kov 5

那是因为扩展:

ds.map(Array("funk", "" + _)).collect 
Run Code Online (Sandbox Code Playgroud)

不按你的想法工作.它扩展到:

ds.map(Array("funk", ((x: Any) => "" + x))).collect 
Run Code Online (Sandbox Code Playgroud)

_阵列中创建扩展为一个功能.根据DataSet的文档,不支持函数.

如果我们采取最小的重现:

val l = List(1,2,3)
val res = l.map(Array("42", "" + _))
Run Code Online (Sandbox Code Playgroud)

并且看到typer扩展(scalac -Xprint:typer),你可以看到:

def main(args: Array[String]): Unit = {
  val l: List[Int] = scala.collection.immutable.List.apply[Int](1, 2, 3);
  val res: List[Object] = 
    l.map[Object, List[Object]]
    (scala.Predef.wrapRefArray[Object]
      (scala.Array.apply[Object]("42", ((x$1: Any) => "".+(x$1))
Run Code Online (Sandbox Code Playgroud)

如果我们隔离特定的相关部分,我们可以看到:

(x$1: Any) => "".+(x$1)
Run Code Online (Sandbox Code Playgroud)

是在数组创建中发生的扩展.