Что означает параметр: _ * в Scala?
Будучи новым для Scala (2.9.1), у меня есть List[Event]
и хотел бы скопировать его в Queue[Event]
, но следующий синтаксис вместо этого дает Queue[List[Event]]
:
val eventQueue = Queue(events)
По какой-то причине следующие работы:
val eventQueue = Queue(events : _*)
Но я хотел бы понять, что он делает, и почему он работает? Я уже посмотрел на подпись функции Queue.apply
:
def apply[A](elems: A*)
И я понимаю, почему первая попытка не работает, но что означает второй? Что такое :
и _*
в этом случае, и почему функция apply
просто принимает Iterable[A]
?
Ответы
Ответ 1
a: A
- это присвоение типа; см. Что такое назначение типов в Scala?
: _*
- специальный экземпляр типа acription, который сообщает компилятору рассматривать один аргумент типа последовательности как последовательность переменных аргументов, то есть varargs.
Вполне возможно создать Queue
с помощью Queue.apply
, который имеет один элемент, который является последовательностью или итерируемым, так что это именно то, что происходит, когда вы даете один Iterable[A]
.
Ответ 2
Это специальное обозначение, которое сообщает компилятору передать каждый элемент как свой собственный аргумент, а не все его как один аргумент. См. здесь.
Это аннотация типа, которая указывает аргумент последовательности и упоминается как "исключение" для общего правила в разделе 4.6.2 спецификации языка "Повторные параметры".
Это полезно, когда функция принимает переменное количество аргументов, например. такую как def sum(args: Int*)
, которую можно вызвать как sum(1)
, sum(1,2)
и т.д. Если у вас есть список, например xs = List(1,2,3)
, вы не можете передать xs
сам, потому что это List
а не Int
, но вы можете передать его элементы с помощью sum(xs: _*)
.