2014-05-22 3 views
1

вот мой код:Scala: Почему l1 ::: l2 не равен l1.:::(l2)?

val l1 = List(1,2,3) 
    val l2 = List(4,5,6) 
    val l1l2_1 = l1 ::: l2 
    val l1l2_2 = l1.:::(l2) 
    val l1l2_3 = l2.:::(l1) 
    println(s"l1 = $l1 \nl2 = $l2 \nl1 ::: l2 = $l1l2_1 \nl1.:::(l2) = $l1l2_2 \nl2.:::(l1) = $l1l2_3 }") 

и вот результат:

l1 = List(1, 2, 3) 
l2 = List(4, 5, 6) 
l1 ::: l2 = List(1, 2, 3, 4, 5, 6) 
l1.:::(l2) = List(4, 5, 6, 1, 2, 3) 
l2.:::(l1) = List(1, 2, 3, 4, 5, 6) } 

Почему l1 ::: l2 не равна с l1.:::(l2)?

+0

С помощью '.' вы меняете, к какому« списку »применяется конкатенация. – millhouse

+0

Возможный дубликат http://stackoverflow.com/questions/15384744/how-to-make-a-right-associative-infix-operator –

ответ

4

Операторы, которые заканчиваются на :, обрабатываются иначе, чем другие. При использовании с нотной записью infix они отменяют свои аргументы - метод вызывается по аргументу справа, а аргумент слева используется как параметр. Таким образом, l1 ::: l2 - это то же самое, что и у l2.:::(l1).

+0

Полезно знать ... но это безумие. Принцип наименьшего удивления, действительно. – acjay

+0

Не то, что сумасшедший. Каждый язык имеет приоритет и ассоциативность! Вы должны иметь дело с этим. – Radian

+0

@acjay, чтобы быть справедливым, этот аспект, упомянутый в каждой вводной книге Scala –

1

Причина: два правила в Scala:
1. : Оператор/метод является правильным ассоциативным.
2. Ассоциативность оператора/методов определяется по знаку последнего имени в названии оператора.

Например:
Любой метод с произвольным именем, но заканчивающиеся :

def myMethod:(a: Any) 

рассматривается как :, так x myMethod: y прав ассоциативный тоже, и выполняется как y.myMethod:(x)

Read more in Programming in Scala book: Basic Types and Operations

Смежные вопросы