Reputation: 6152
Can someone please walk through this piece of scala syntax for me? I am new to the language, coming from Java.
val map = Map(seq map { a => a.key -> a }: _*)
In particular I understand a => a.key -> a
is an anonymous function that returns a pair(?) (a.key, a)
for each a
, but what does : _*
, { }
do and why is there a space between seq
and map
? Are they arguments to the Map
constructor?
Upvotes: 2
Views: 147
Reputation: 5010
In addition to Ramesh's answer.. your seq is most likely a Scala collection. Scala collections have numerous methods like map, filter, fold, reduce etc etc. So map is a method call on seq which is called without using the dot operator. This is allowed in Scala iff the method takes a single parameter.
The _* is somewhat weirder. Immutable Map requires a vararg as parameter. But the map method on seq will return a Map. The _* is in position of "type". By type, I simply mean, if I write i: Int, so Int is the type. So when an object's type is marked as _*, automatic type conversion takes place by the compiler which uses a factory to convert the object into a vararg. Like in Java, varargs can only appear as last parameter in a parameter list.
Upvotes: 2
Reputation: 41987
: _*
tells the compiler to pass each element of arr as its own argument to the function, rather than all of it as a single argument. Or to say in other words it is a special instance of type ascription which tells the compiler to treat a single argument of a sequence type as a variable argument sequence, i.e. varargs
.
The _*
type annotation is covered in "4.6.2 Repeated Parameters
" of the SLS.
The last value parameter of a parameter section may be suffixed by “*”, e.g. (..., x:T *). The type of such a repeated parameter inside the method is then the sequence type scala.Seq[T]. Methods with repeated parameters T * take a variable number of arguments of type T . That is, if a method m with type (p1 : T1, . . . , pn : Tn,ps : S*)U is applied to arguments (e1, . . . , ek) where k >= n, then m is taken in that application to have type (p1 : T1, . . . , pn : Tn,ps : S, . . . , ps0S)U, with k ¡ n occurrences of type S where any parameter names beyond ps are fresh. The only exception to this rule is if the last argument is marked to be a sequence argument via a _* type annotation. If m above is applied to arguments (e1, . . . , en,e0 : _*), then the type of m in that application is taken to be (p1 : T1, . . . , pn : Tn,ps :scala.Seq[S])
{ }
indicates a block of code
, which is composed of multiple statements
and declarations
, and whose value is that of the last statement. If you need declarations, multiple statements, an import or anything like that, you need curly braces
Scala has a special punctuation-free
syntax for invoking methods that take one argument. General rule is Scala methods that take a single parameter can be invoked without dots or parentheses
.
Upvotes: 4