我不确定为什么这个简单的代码不起作用

时间:2018-01-28 04:56:10

标签: ruby

我希望有人输入数字"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”。

为什么会这样?

2 个答案:

答案 0 :(得分:5)

让我们先来看看你获得错误结果的原因。

如果a等于falsenil falsy ,意味着逻辑false),a or b会返回值b。如果a等于任何其他值( truthy ,意味着逻辑true),则a or b会返回a

假设我们有一个表达式a op1 b op2 c,其中op1op2是运算符(例如a == b or c)。可以对此(a op1 b) op2 ca op1 (b op2 c)进行评估,其中括号具有最高优先级。

Ruby的运算符(大多数实现为方法)的优先级为here。请注意,==的优先级高于or。此外,对于任何给定的运算符opa 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#betweenRange#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

在这里,您要将变量的值与右侧文字进行比较。