Я довольно плохо знаком с языком программирования Scala и испытывал что-то stucked в моем уме, в то время как я следовал примечаниям лекции в здесь.
Я думаю, что не мог действительно понять, как оператор недостатков работает, вот некоторые вещи, которые я попробовал:
Я создал генератор псевдослучайного числа, затем попытался создать список одного случайного значения:
scala> val gen = new java.util.Random
gen: java.util.Random = java.util.Random@1b27332
scala> gen nextInt 3 :: Nil
:7: error: type mismatch;
found : List[Int]
required: Int
gen nextInt 3 :: Nil
^
Но это пыталось передать Список (3) nextnt методу. Когда я использовал паратезисы, не было никакой проблемы
scala> (gen nextInt 3) :: Nil
res69: List[Int] = List(1)
Мне было любопытно на предмет порядка выполнения, таким образом, я создал функцию для проверки его
scala> def pr(i:Int):Int = { println(i); i }
pr: (i: Int)Int
scala> pr(1) :: pr(2) :: pr(3) :: Nil
1
2
3
res71: List[Int] = List(1, 2, 3)
Как замечено в выводах, порядок выполнения совпадает с порядком появления. Затем я думал, что это могло бы быть о функции 'nextInt', затем я попробовал следующее:
scala> 1 + 2 :: Nil
res72: List[Int] = List(3)
Это сначала выполнило дополнение, и после того, как это подставляет, выполняется. Таким образом, вот вопрос: Между чем различие gen nextInt 3 :: Nil
и 1 + 2 :: Nil
?
Здесь есть две вещи, вызывающие беспокойство: приоритет и фиксация . Как упоминалось в 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.
Речь идет о старшинстве, а не о порядке выполнения. +
имеет более высокий приоритет, чем ::
, поэтому a + b :: c
парсится как (a + b) :: c
. Однако вызовы инфиксных методов с обычными именами имеют меньший приоритет, поэтому a foo b c
разбирается как a foo (b c)
.
См. этот вопрос для списка операторов, упорядоченных по старшинству в scala.