Понимание инфикса метода вызова и минус оператора (: :) в Scala
-
02-10-2019 - |
Вопрос
Я вполне новый для языка программирования Scala, и пытался что-то вотворить в моих мыслях, пока я следовал лекции в нотах здесь.
Я думаю, что я не мог понять, как работает минус оператора, вот некоторые вещи, которые я пытался:
Я создал генератор псевдослучайного номера, затем попытался создать список из одного случайного значения:
scala> val gen = new java.util.Random
gen: java.util.Random = java.util.Random@1b27332
scala> gen nextInt 3 :: Nil
<console>:7: error: type mismatch;
found : List[Int]
required: Int
gen nextInt 3 :: Nil
^
Но он пытался пройти список (3) к методу NextNT. Когда я использовал Paratheses, проблем не было
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. Различия касаются в основном операторы, заканчивающиеся в =
, хотя.
Что касается фиксатор, почти все в 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
. Отказ Однако вызовы метода Infix с регулярными именами имеют более низкий приоритет, поэтому a foo b c
анализаторы как a foo (b c)
.
Видеть этот вопрос Для списка операторов, приказанных их приоритетом в Scala.