Понимание инфиксного вызова метода и оператора недостатков (: :) в Scala

Я довольно плохо знаком с языком программирования 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?

19
задан ciuncan 17 October 2016 в 11:43
поделиться

2 ответа

Здесь есть две вещи, вызывающие беспокойство: приоритет и фиксация . Как упоминалось в 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.

42
ответ дан 30 November 2019 в 02:56
поделиться

Речь идет о старшинстве, а не о порядке выполнения. + имеет более высокий приоритет, чем ::, поэтому a + b :: c парсится как (a + b) :: c. Однако вызовы инфиксных методов с обычными именами имеют меньший приоритет, поэтому a foo b c разбирается как a foo (b c).

См. этот вопрос для списка операторов, упорядоченных по старшинству в scala.

3
ответ дан 30 November 2019 в 02:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: