Understanding infix method call and cons operator(::) in Scala

巧了我就是萌 提交于 2019-12-02 17:14:28

There are two things of concern here: precedence and fixity. As sepp2k mentioned, this question on Stack Overflow explains the precedence, thought the rules, as quoted, are not complete enough, and there were very small changes from Scala 2.7 to Scala 2.8. Differences concern mostly operators ending in =, though.

As for fixity, almost everything in Scala is read left to right, which is what programmers are used to. In Scala, however, operators ending in : are read right to left.

Take, then, this example:

1 + 2 :: Nil

First, precedence. What has most precedence, + or :? According to the table, + has precedence over :, so the addition is done first. Therefore, the expression is equal to this:

((1).+(2)) :: Nil

Now there's no precedence conflict, but since :: ends in :, it has a diferent fixity. It is read right to left, therefore:

Nil.::((1).+(2))

On the other hand, in this:

gen nextInt 3 :: Nil

The operator :: has precedence over nextInt, because : has precedence over all letters. Therefore, and remembering its fixity, it becomes:

gen nextInt Nil.::(3)

Which then becomes

gen.nextInt(Nil.::(3))

At which point the error is obvious.

PS: I'm writing (1).+(2) instead of 1.+(2) because, at the time of this writing, 1. is interpreted as a double number, making 1.+(2) an infix expression adding the double 1.0 to 2. This syntax is deprecated as of Scala 2.10.0, and will probably not be present on Scala 2.11.

sepp2k

It's about precedence not execution order. + has higher precedence than ::, so a + b :: c parses as (a + b) :: c. However infix method calls with regular names have lower precedence, so a foo b c parses as a foo (b c).

See this question for a list of operators ordered by their precedence in scala.

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