Параметры метода Scala - объединение переменных аргументов и параметров по умолчанию - PullRequest
0 голосов
/ 27 октября 2018

Возможно ли объединить переменные аргументы и параметры по умолчанию в определении функции метода Scala?В частности, я пытаюсь написать метод исправления со следующей подписью:

def patch(body: String, contentType: ContentType = ContentType.APPLICATION_JSON, customHeaders: (String, String)*)

Я получаю ошибку Parameter section with *-parameter cannot have default arguments.Поэтому я предполагаю, что это был вопрос упорядочения параметров.Однако я должен указать * -параметры последними.

Мои вопросы:

  • Почему * -параметр должен быть последним?Неужели компилятор может легко анализировать аргументы?

  • Почему параметр * не может следовать после аргументов по умолчанию?Я полагаю, что тот же аргумент применяется там, где компилятору проще анализировать аргументы, поскольку аргументы по умолчанию и аргументы переменных являются необязательными.

1 Ответ

0 голосов
/ 27 октября 2018

Почему * -параметр должен быть последним?

Технически, даже если * -параметр не ограничен последним, компилятор должен иметь возможность его вычислитьиз.Эта SO ссылка дает некоторое представление (хотя и неофициальное) о возможном обосновании.

Почему * -параметр не может следовать после аргументов по умолчанию?

Если * -параметр после аргумента по умолчанию был разрешен, была бы неоднозначность, в которой переменным аргумента должны быть назначены предоставленные параметры в некоторых случаях.Например:

def foo(a: String = "hi", bs: String*) = a + " " + bs.mkString(" ")

foo("hello", "world")  // Should "hello" go to `a` or be a part of `bs`?

Обратите внимание, что технически это ограничение также может быть снято, скажем, путем требования явного присвоения аргумента переменной в случаях, когда возникает неоднозначность (например, foo(a="hello", "world")).

Чтобы обойтиВ качестве ограничения вы можете прибегнуть к каррированию (что позволяет вам иметь * -параметр на список аргументов):

def bar(s: String, i: Int = 1, ts: (String, String)*) =
  ts.map(t => (t._1 + s*i, t._1 + s*i))
// <console>:23: error: a parameter section with a `*'-parameter is not allowed to have default arguments
//        def bar(s: String, i: Int = 1, ts: (String, String)*) = {

def bar(s: String, i: Int = 1)(ts: (String, String)*) =
  ts.map(t => (t._1 + s*i, t._2 + s*i))

bar("!", 2)(("a", "b"), ("c", "d"))
// res1: Seq[(String, String)] = ArrayBuffer((a!!,b!!), (c!!,d!!))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...