Почему компилятор Scala не работает с аннотацией «no»: _ * 'здесь разрешено », когда Row принимает varargs? - PullRequest
0 голосов
/ 03 сентября 2018

Я хотел бы создать 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:_*

Что я пропустил?

Ответы [ 2 ]

0 голосов
/ 03 сентября 2018

Этот минимальный пример может объяснить лучше, почему то, что вы хотите сделать, не разрешено:

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
0 голосов
/ 03 сентября 2018

Решил, добавив посредника Seq:

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

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

    Row(
      args:_*
    )
}

Но все же я не знаю, почему это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...