Scala: конструктор, принимающий Seq или varargs - PullRequest
20 голосов
/ 12 августа 2011

Я предполагаю, что по причинам совместимости типом параметров vararg Any* является Массив [Любой] - пожалуйста, исправьте это, если я ошибаюсь. Однако это не объясняет следующую ошибку:

class Api(api_url: String, params: Seq[(String, String)]) {
  def this(api_url: String, params: (String, String)*)
    = this(api_url, params.seq)
}

Этот код не компилируется, но выдает предупреждение:

двойное определение: Конструктор Api: (api_url: String, params: (String, String) *) API и конструктор Api: (api_url: String, params: Seq [(String, String)]) Api в строке 13 имеет тот же тип после стирания: (api_url: java.lang.String, params: Seq) Api

Итак, как мне определить конструктор, принимающий varargs или последовательность?

Ответы [ 3 ]

31 голосов
/ 12 августа 2011

Метод, принимающий varargs, также всегда принимает последовательность, поэтому нет необходимости определять вспомогательный конструктор или перегруженный метод.

Учитывая

class Api(api_url: String, params: (String, String)*)

вы можете назвать это так

new Api("url", ("a", "b"), ("c", "d"))

или

val seq = Seq(("a", "b"), ("c", "d"))
new Api("url", seq:_*)

Также, по вашему вопросу вы звонитеМетод seq для параметра params.Это, вероятно, не делает то, что вы хотели.seq используется для обеспечения того, чтобы операции с результирующей коллекцией выполнялись последовательно, а не параллельно.Этот метод был представлен с параллельными коллекциями в Scala версии 2.9.0.

То, что вы, вероятно, хотели использовать, было toSeq, которое возвращает коллекцию, которую она использует при преобразовании в Seq (или само, если оно ужеSeq).Но так как параметры varargs уже набраны как Seq, это все равно не работает.

10 голосов
/ 12 августа 2011

Нет: на самом деле, Any* фактически почти идентично Seq[Any], а не Array[Any].

Чтобы устранить неоднозначность между ними, вы можете использовать технику, чтобы добавить фиктивный неявный параметр, чтобы отличить сигнатуру:

class Api(api_url: String, params: Seq[(String, String)]) {
  def this(api_url: String, params: (String, String)*)(implicit d: DummyImplicit) =
    this(api_url, params)
}
1 голос
/ 15 февраля 2016

Полагаю, вы хотели бы сделать вызовы методов красивее, поэтому явный вызов с помощью _* не вариант.В этом случае вы можете решить проблему с перегрузкой метода.

class Api(api_url: String, params: Seq[(String, String)]) {
  def this(api_url: String, param : (String, String), params: (String, String)*)
    = this(api_url, param +: params)
  def this(api_url: String)
    = this(api_url, Seq())
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...