Здесь есть две проблемы: приоритет и фиксированность . Как упоминалось в sepp2k, этот вопрос о переполнении стека объясняет приоритет, считая, что приведенные правила недостаточно полны, и произошли очень небольшие изменения с Scala 2.7 до Scala 2.8. Различия касаются в основном операторов, оканчивающихся на =
.
Что касается fixity , то почти все в Scala читается слева направо, к чему привыкли программисты. Однако в Scala операторы, оканчивающиеся на :
, читаются справа налево.
Возьмем, к примеру, этот пример:
1 + 2 :: Nil
Во-первых, приоритет. Что имеет наибольшее преимущество, +
или :
? Согласно таблице, +
имеет приоритет над :
, поэтому добавление выполняется первым. Следовательно, выражение равно этому:
((1).+(2)) :: Nil
Теперь нет конфликта приоритетов, но, поскольку ::
оканчивается на :
, он имеет другую фиксированность. Читается справа налево, поэтому:
Nil.::((1).+(2))
С другой стороны, в этом:
gen nextInt 3 :: Nil
Оператор ::
имеет приоритет над nextInt
, потому что :
имеет приоритет над всеми буквами. Поэтому, вспоминая свою стойкость, она становится:
gen nextInt Nil.::(3)
Который затем становится
gen.nextInt(Nil.::(3))
В этот момент ошибка очевидна.
PS: я пишу (1).+(2)
вместо 1.+(2)
, потому что на момент написания этой статьи 1.
интерпретировалось как двойное число, делая 1.+(2)
инфиксным выражением с добавлением двойного 1,0 к 2. Этот синтаксис устарел в Scala 2.10.0 и, вероятно, не будет присутствовать в Scala 2.11.