Będąc nowym w Scali (2.9.1), mam a List[Event]
i chciałbym go skopiować do a Queue[Event]
, ale następująca składnia daje Queue[List[Event]]
zamiast tego a:
val eventQueue = Queue(events)
Z jakiegoś powodu działa:
val eventQueue = Queue(events : _*)
Ale chciałbym zrozumieć, co to robi i dlaczego działa? Spojrzałem już na podpis Queue.apply
funkcji:
def apply[A](elems: A*)
I rozumiem, dlaczego pierwsza próba nie działa, ale jakie jest znaczenie drugiej? Co to jest :
iw _*
tym przypadku i dlaczego apply
funkcja nie przyjmuje po prostu znaku Iterable[A]
?
źródło
def sum(xs: _*)
zgłasza błąd: niezwiązany typ wieloznaczny 'xs: int
oznacza, że typ xs to int, przechodząc przez to jest powyższą składnią w scali, gdziexs: _*
oznacza, że xs jest rzutowane na poszczególne elementy.def sum(args: Int*)
a ty nazywasz go z wieloznacznym typu „rodzajowe” var-args:val a = sum(xs: _*)
. Pomyśl o_*
„Przekazuję Int *, String * lub cokolwiek *, co jest zdefiniowane w sygnaturze metody”Dla osób korzystających z Pythona:
_*
Operator Scali jest mniej więcej odpowiednikiem operatora * -operatora Pythona .Przykład
Konwersja przykładu scala z linku dostarczonego przez Luigiego Plinge'a :
def echo(args: String*) = for (arg <- args) println(arg) val arr = Array("What's", "up", "doc?") echo(arr: _*)
do Pythona wyglądałoby następująco:
def echo(*args): for arg in args: print "%s" % arg arr = ["What's", "up", "doc?"] echo(*arr)
i oba dają następujący wynik:
Różnica: rozpakowywanie parametrów pozycyjnych
Podczas gdy
*
operator Pythona może również zajmować się rozpakowywaniem parametrów pozycyjnych / parametrów dla funkcji o stałej arity:def multiply (x, y): return x * y operands = (2, 4) multiply(*operands)
Robiąc to samo ze Scalą:
def multiply(x:Int, y:Int) = { x * y; } val operands = (2, 4) multiply (operands : _*)
zawiedzie:
Ale można osiągnąć to samo ze scalą:
def multiply(x:Int, y:Int) = { x*y; } val operands = (2, 4) multiply _ tupled operands
Według Lorrina Nelsona tak to działa:
Dalsze czytanie:
źródło