Приоритет оператора для And/&& в Ruby [дублировать]

StackOverflow https://stackoverflow.com/questions/1840488

  •  12-09-2019
  •  | 
  •  

Вопрос

На этот вопрос уже есть ответ здесь:

У меня есть вопрос относительно ключевых слов 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

Другие советы

Причина проста:приоритет.Как вы сказали, порядок таков:

  1. &&
  2. =
  3. и

С тех пор как && имеет приоритет над =, оператор оценивается следующим образом:

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top