Приоритет оператора для And/&& в Ruby [дублировать]
-
12-09-2019 - |
Вопрос
На этот вопрос уже есть ответ здесь:
- Разница между “и” и && в Ruby? 7 ответов
У меня есть вопрос относительно ключевых слов and/&&/= в Ruby.
В документах ruby говорится, что приоритет для упомянутых ключевых слов равен:(1)&&, (2)=, (3) и.
У меня есть этот фрагмент кода, который я написал:
def f(n)
n
end
if a = f(2) and b = f(4) then
puts "1) #{a} #{b}"
end
if a = f(2) && b = f(4) then
puts "2) #{a} #{b}"
end
Результатом является:
1) 2 4 [Ожидается]
2) 4 4 [Почему?]
По какой-то причине использование && приводит к тому, что и a, и b оцениваются как 4?
Решение
Я не совсем понимаю вопрос, который вы задаете.Я имею в виду, что у тебя есть уже ответьте на него сами, до того, как даже задавая этот вопрос: &&
связывает крепче, чем =
в то время как and
связывает менее плотно, чем =
.
Итак, в первом случае выражение вычисляется следующим образом:
( a=f(2) ) and ( b=f(4) )
( a= 2 ) and ( b=f(4) )
2 and ( b=f(4) ) # a=2
2 and ( b= 4 ) # a=2
2 and 4 # a=2; b=4
4 # a=2; b=4
Во втором случае оценка производится следующим образом:
a = ( f(2) && ( b=f(4) ) )
a = ( 2 && ( b=f(4) ) )
a = ( 2 && ( b= 4 ) )
a = ( 2 && 4 ) # b=4
a = 4 # b=4
4 # b=4; a=4
Другие советы
Причина проста:приоритет.Как вы сказали, порядок таков:
- &&
- =
- и
С тех пор как &&
имеет приоритет над =
, оператор оценивается следующим образом:
if a = (f(2) && (b = f(4))) then
Что приводит к:
if a = (2 && 4) then
Когда x
и y
являются целыми числами, x && y
ВОЗВРАТ y
.Таким образом 2 && 4
приводит к a = 4
.
Для сравнения, первый из них оценивается следующим образом:
if (a = f(2)) and (b = f(4)) then
От Программирование на Ruby 1.9:
Единственное различие в этих двух формах - это приоритет (
and
связывает ниже, чем&&
).
Я не знаю конкретных правил, которые могут помочь в этой ситуации, но давайте использовать приоритеты операций.Используя правила приоритетов, мы можем разделить вычисление второго выражения на несколько шагов
1 f(2) && b => expr1
2 expr1 = f(4) => expr2
3 a = expr2
Очевидно, что на шаге 2 мы получаем некорректную ситуацию - в левой части = находится rvalue - временный объект, которому нельзя присвоить какое-либо значение.Я предполагаю, что синтаксический анализатор нарушает правила приоритетного вычисления выражений, когда сталкивается с подобными ситуациями.Более подробную информацию о вычислениях выражений можно найти здесь здесь
если вы измените свой код подобным образом, вы получите то, что ожидаете
def f(n)
n
end
if (a = f(2) and b = f(4)) then
puts "1) #{a} #{b}"
end
if (a = f(2) and b = f(4)) then
puts "2) #{a} #{b}"
end
1) 2 4
2) 2 4