Почему нотация объектов в Scala, по-видимому, устраняет ассоциативность правой стороны методов, заканчивающихся на ':'?

В настоящее время я вхожу в Scala и меня интересует, каково это использование нотации объектов при вызове методов, заканчивающихся на ':'. Поскольку имя метода, оканчивающееся на ":", обычно вызывает правую ассоциативность, похоже, это меняется при вызове такого метода с нотацией объекта.

Пример:

scala> 3 +: List(1,2) 
res1: List[Int] = List(3, 1, 2) 

scala> List(1,2) +: 3 // does not compile due to right side associativity

scala> (List(1,2)).+:(3) 
res2: List[Int] = List( 3, 1, 2)

Теперь я не понимаю, почему функция правой ассоциативности отключается с помощью записи объекта. Может кто-нибудь объяснить это или ссылку на документацию по этому вопросу?

1 ответ

Решение

Из спецификации"Операции с инфиксами":

Ассоциативность оператора определяется последним символом оператора. Операторы, оканчивающиеся двоеточием `:', являются ассоциативными справа. Все остальные операторы левоассоциативны.

метод +: определяется в списке, поэтому (List(1,2)).+:(3) работает. Его реализация такова, что элемент находится спереди, что эквивалентно 3 :: List(1, 2), но это не имеет значения здесь.

Использование инфиксной записи List(1,2) +: 3 не будет работать, потому что (как указано в спецификации) все инфиксные операторы, заканчивающиеся двоеточием, являются ассоциативными справа, что означает, что "правая сторона" использует оператор с "левой стороной" в качестве параметра, а не наоборот.

В принципе,

1 +: 2 +: 3 +: List(4, 5) 

а также

List(4, 5).+:(3).+:(2).+:(1)

имеют одинаковый эффект (я знаю, что это уже довольно очевидно в вашем вопросе, но я просто подчеркиваю правильную ассоциативность).

Итак, чтобы ответить на ваш вопрос одним простым предложением: не то, что правая сторона ассоциативности удаляется в нотации объектов, это скорее то, что она добавляется в нотации инфикс, а только для методов, заканчивающихся двоеточием.

Другие вопросы по тегам