Reputation: 15965
I just started learning Scala, and I've noticed that :
is used in many places. Most of the time, the :
usage makes sense, e.g. after parameter names or method declarations. The following usage confuses me, however:
val a = Seq[String]("a", "b")
a :+ "c"
or
def myMethod(varargs: String*) {
// ...
}
val a = Seq[String]("a", "b", "c")
myMethod(a:_*)
What exactly is the :
doing in these cases? Why can't I call a._*
directly?
Upvotes: 0
Views: 91
Reputation: 306
The significance of the colon in Scala varies according to context.
As you note, it separates an identifier in a declaration from its type.
It can also appear as part of an operator involving a sequence.
Since an operator in Scala is really just a method, its use here is arbitrary, but you can rely on the convention that the colon is on the side of a binary operator that points to the sequence.
So your example
a :+ "c"
Appends the string "c"
to a
sequence of strings, while
"c" +: a
Prepends the string to the sequence. (Or, more precisely in the case of an immutable sequence, returns a new sequence resulting from the prepend/append operation. See documentation)
Your final example
myMethod(a: _*)
(Which I had to look up thanks for teaching! see documentation) tells the compiler to expand the sequence as varargs (rather than as a single argument).
Upvotes: 0
Reputation: 11244
It is telling the compiler that you want your sequence to be taken apart and supplied as separate parameters.
def myMethod(varargs: String*) = {
// varargs is a Seq
val x:Seq[String] = varargs
}
// Calling it is different
myMethod("a", "b")
// To call using a seq, you need to signal the compiler
myMethod(mySeqOfString: _*)
// They choose the `:` because this would be valid too:
myMethod(myString: String)
Int the other example you gave a :+ "c"
the :
has a different meaning. It's simply part of the method name. They could have named it append
, but they chose :+
. The reason is that the :
in +:
has a special meaning: bind to the right
. This allows for "c" +: a
. So for sake of consistency they probably chose :+
for append and +:
for prepend.
Upvotes: 2
Reputation: 206816
The two usages that you are asking about are two completely different cases.
a :+ "c"
The :
doesn't mean anything by itself here; it's part of a method named :+
, which appends an element to a Seq
.
myMethod(a:_*)
Here, you have a method myMethod
which takes a variable number of arguments. You want to use the Seq
to fill the arguments; the : _*
indicates that you want to do that (rather than pass the Seq
itself as the first argument of the method).
Note that :
has a special meaning if a method name ends with :
(not if it begins with :
as in your first example). In that case, the method will be right-associative; it means that the method will be called on the thing on the right, with the thing on the left as the argument, rather than the reverse.
Upvotes: 4
Reputation: 144136
:+
is a method on Seq[A]
which appends the given item to the sequence.
In the second example, myMethod(a : _*)
the a : _*
is used to pass a sequence as the variable argument list to the myMethod
function.
Upvotes: 0