Почему нотация объектов в 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)
имеют одинаковый эффект (я знаю, что это уже довольно очевидно в вашем вопросе, но я просто подчеркиваю правильную ассоциативность).
Итак, чтобы ответить на ваш вопрос одним простым предложением: не то, что правая сторона ассоциативности удаляется в нотации объектов, это скорее то, что она добавляется в нотации инфикс, а только для методов, заканчивающихся двоеточием.