Scala's '::' operator, how does it work?

自作多情 提交于 2019-11-27 03:11:05

From the Spec:

6.12.3 InfixOperations An infix operator can be an arbitrary identifier. Infix operators have precedence and associativity defined as follows.

...

The associativity of an operator is determined by the operator’s last character. Operators ending in a colon ‘:’ are right-associative. All other operators are left- associative.

You can always see how these rules are applied in Scala by printing the program after it has been through the 'typer' phase of the compiler:

scala -Xprint:typer -e "1 :: Nil"

val r: List[Int] = {
  <synthetic> val x$1: Int = 1;
  immutable.this.Nil.::[Int](x$1)
};

It ends with a :. And that is the sign, that this function is defined in the class to the right (in List class here).

So, it's List(Foo(2)).::(Foo(40)), not Foo(40).::(List(Foo(2))) in your example.

One aspect missing in the answers given is that to support :: in pattern matching expressions:

List(1,2) match {
  case x :: xs => println(x + " " + xs)
  case _ => println("")
}

A class :: is defined :

final case class ::[B](private var hd: B, private[scala] var tl: List[B]) 

so case ::(x,xs) would produce the same result. The expression case x :: xs works because the default extractor :: is defined for the case class and it can be used infix.

Surya Suravarapu

The class Foo I just defined does not have the :: operator, so how is the following possible:

Foo(40) :: List(Foo(2))

If the method name ends with a colon (:) the method is invoked on the right operand, which is the case here. If the method name doesn't end with colon, the method is invoked on the left operand. For example, a + b, + is invoked on a.

So, in your example, :: is a method on its right operand, which is a List.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!