我希望有人输入数字"1"
,"2"
或"3"
,如果数字正确,请说"ok"
。如果没有,我想说"enter 1 or 2 or 3"
。
这是我的代码:
puts "enter 1 or 2 or 3"
num = gets.to_i
if num == 1 or 2 or 3
puts "ok"
else
puts "enter 1 or 2 or 3"
end
当我输入错误的答案,例如"e"
或"p"
时,它仍然显示“ok”。
为什么会这样?
答案 0 :(得分:5)
让我们先来看看你获得错误结果的原因。
如果a
等于false
或nil
( falsy ,意味着逻辑false
),a or b
会返回值b
。如果a
等于任何其他值( truthy ,意味着逻辑true
),则a or b
会返回a
。
假设我们有一个表达式a op1 b op2 c
,其中op1
和op2
是运算符(例如a == b or c
)。可以对此(a op1 b) op2 c
或a op1 (b op2 c)
进行评估,其中括号具有最高优先级。
Ruby的运算符(大多数实现为方法)的优先级为here。请注意,==
的优先级高于or
。此外,对于任何给定的运算符op
,a op b op c
都会被(a op b) op c
评估。
因此评估表达式num == 1 or 2 or 3
((num == 1) or 2) or 3
现在考虑此表达式的值,具体取决于num
的值。
num = 1
((num == 1) or 2) or 3 => (true or 2) or 3 => true or 3 => true
num != 1
((num == 1) or 2) or 3 => (false or 2) or 3 => 2 or 3 => 2
以下是获得所需结果的一些方法。
(num == 1) or (num == 2) or (num == 3)
(num == 1) || (num == 2) || (num == 3)
[1, 2, 3].include?(num)
[1, 2, 3] & [num] == [num]
([num] - [1, 2, 3]).empty?
由于运算符的优先规则,前两个表达式中不需要括号,但可以认为它们澄清了代码,至少对于某些读者来说。 (我会包括他们。)
关于使用or
或||
之间的选择,请参阅this SO queston,尤其是第二个答案。实际上,很少使用or
。
请参阅Array#include?,Array#&和Array#-。
为了完善可能性,可以想象使用案例陈述。
case num
when 1, 2, 3 then true
else false
end
如果在此处num
的可接受值形成范围,则可以编写以下任一项。
num.between?(1, 3)
(1..3).cover?(num)
(num >= 1) && (num <= 3)
请参阅Comparable#between和Range#cover?。同样,后者的括号是可选的。
答案 1 :(得分:1)
在您的代码中,num == 1 or 2 or 3
始终评估为true
,因为2
被视为逻辑正确,并始终使用or`` operator with logically true value returns a
true`结果。
比较的正确方法是这样的
puts "enter 1 or 2 or 3"
num = gets.to_i
if num == 1 or num == 2 or num == 3
puts "ok"
else
puts "enter 1 or 2 or 3"
end
在这里,您要将变量的值与右侧文字进行比较。