我想用多个参数创建一个Row而不知道它们的编号。我在Scala中这样写:

def customRow(balance: Int,
              globalGrade: Int,
              indicators: Double*): Row = {
    Row(
      balance,
      globalGrade,
      indicators:_*
    )
}


Spark GitHub上,考虑到Row方法,:_*对象似乎接受apply表示法:

def apply(values: Any*): Row = new GenericRow(values.toArray)


但是在编译时,似乎不允许这样做:

Error:(212, 19) no ': _*' annotation allowed here
(such annotations are only allowed in arguments to *-parameters)
        indicators:_*


我错过了什么?

最佳答案

这个最小的示例可能会更好地解释为什么不允许您执行以下操作:

def f(a: Int, b: Int, c: Int, rest: Int*) = a + b + c + rest.sum

val ns = List(99, 88, 77)

f(11, 22, 33, 44, ns:_*) // Illegal
f(11, 22, 33,     ns:_*) // Legal
f(11, 22,         ns:_*) // Illegal


基本上,您只能使用:_*语法直接将序列作为vararg参数rest传递,但是它全有还是全无。序列的项目不会在simple和vararg参数之间共享,并且vararg参数无法从简单参数和提供的序列中收集值。

在您的情况下,您尝试调用Row,就好像它有两个简单参数,然后是一个vararg,但这不是事实。自己创建序列时,就是要使其正确适合签名。

请注意,在动态类型的编程语言中,这通常不是问题。例如,在Python中:

>>> def f(a, b, c, *rest):
    return a + b + c + sum(rest)

>>> ns = [99, 88, 77]
>>> f(11, 22, 33, 44, *ns)
374
>>> f(11, 22, 33, *ns)
330
>>> f(11, 22, *ns)
297

关于scala - 当Row接受varargs时,为什么Scala编译器会失败,并显示“在此不允许':_ *'批注”?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52152680/

10-09 05:51