Max
Max

Reputation: 15965

What does the : mean after a value in Scala?

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

Answers (4)

chaslewis
chaslewis

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

EECOLOR
EECOLOR

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

Jesper
Jesper

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

Lee
Lee

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

Related Questions