La precedencia de operadores para Y / && en Ruby [duplicado]
-
12-09-2019 - |
Pregunta
Esta pregunta ya tiene una respuesta aquí:
- entre “y” y && en Ruby? 7 respuestas
Tengo una pregunta con respecto a los y / && / = palabras clave en Ruby.
Los docs rubí dicen que la prioridad para las palabras clave mencionados es: (1) &&, (2) =, (3) y
.Tengo este fragmento de código que he escrito:
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
La salida es:
1) 2 4 [Esperado]
2) 4 4 [ ¿Por qué ?]
Por alguna razón, el uso de la && hace que tanto A como B para evaluar a 4?
Solución
No entiendo muy bien la pregunta que usted está pidiendo. Es decir, usted tiene ya dado la respuesta usted mismo, antes , incluso haciendo la pregunta:. &&
une más apretado que =
mientras and
se une menos fuertemente que =
Así, en el primer caso, la expresión se evalúa de la siguiente manera:
( 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
En el segundo caso, la evaluación es como sigue:
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
Otros consejos
La razón es simple: la precedencia. Como usted dice, el orden es:
- &&
- =
- y
Desde &&
ha precedencia sobre =
, la declaración se evalúa del siguiente modo:
if a = (f(2) && (b = f(4))) then
que se traduce en:
if a = (2 && 4) then
Cuando x
y y
son números enteros, x && y
vuelve y
. resultados así 2 && 4
en a = 4
.
Para efectos de comparación, el primero se evalúa como esto:
if (a = f(2)) and (b = f(4)) then
La única diferencia en las dos formas es precedencia (
and
une más baja que&&
).
No sé las reglas específicas que pueden ayudar en esta situación, pero vamos a utilizar las prioridades de las operaciones. Utilizando las reglas de prioridades, podemos dividir el cálculo de la segunda expresión en varios pasos
1 f(2) && b => expr1
2 expr1 = f(4) => expr2
3 a = expr2
obvio que en el paso 2 obtenemos una situación incorrecta - en el lado izquierdo de la = es rvalue - objeto temporal, que no puede ser asigna por cualquier valor. Asumo que el analizador sintáctico romper las reglas de evaluación prioritaria de expresiones cuando el encuentro que este tipo de situaciones. Más detalles sobre el cálculo de expresiones se pueden encontrar aquí
si modifica su código como éste obtendrá lo que espera
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