首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么Scala编译器会失败,并显示"no ':_*‘annotation allowed here“,而Row却接受varargs?

为什么Scala编译器会失败,并显示"no ':_*‘annotation allowed here“,而Row却接受varargs?
EN

Stack Overflow用户
提问于 2018-09-03 23:34:03
回答 2查看 5.4K关注 0票数 15

我想创建一个具有多个参数的Row,而不知道它们的数量。我用Scala写了类似这样的东西:

代码语言:javascript
运行
复制
def customRow(balance: Int,
              globalGrade: Int,
              indicators: Double*): Row = {
    Row(
      balance,
      globalGrade,
      indicators:_*
    )
}

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

代码语言:javascript
运行
复制
def apply(values: Any*): Row = new GenericRow(values.toArray)

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

代码语言:javascript
运行
复制
Error:(212, 19) no ': _*' annotation allowed here
(such annotations are only allowed in arguments to *-parameters)
        indicators:_*

我错过了什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-09-04 02:18:18

这个最小的例子可能会更好地解释为什么你想做的事情是不允许的:

代码语言:javascript
运行
复制
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中:

代码语言:javascript
运行
复制
>>> 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
票数 19
EN

Stack Overflow用户

发布于 2018-09-03 23:50:54

通过添加中间序列解决了该问题:

代码语言:javascript
运行
复制
def customRow(balance: Int,
              globalGrade: Int,
              indicators: Double*): Row = {

  val args = Seq(
    balance,
    globalGrade
  ) ++ indicators

    Row(
      args:_*
    )
}

但我仍然不知道它为什么会起作用。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52152680

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档