理解Ruby中的if条件中的“||”OR运算符
简而言之,为什么以下三条线的影响不一样?
if @controller.controller_name == "projects" || @controller.controller_name == "parts" if @controller.controller_name == ("projects" || "parts") if @controller.controller_name == "projects" || "parts"
第一个给出了我想要的结果,但实际上有更多选项而不仅仅是项目和部分,使用该表单创建了一个详细的语句。 另外两个更紧凑,但不给我相同的结果。
||的确切语义 是:
- 如果第一个表达式不是nil或false,则返回它
- 如果第一个表达式为nil或false,则返回第二个表达式
所以你的第一个表达式是,如果@controller.controller_name == "projects"
,则表达式短路并返回true
。 如果没有,它会检查第二个表达式。 第二个和第三个变体基本上if @controller.controller_name == "projects"
,因为"projects" || "parts"
"projects" || "parts"
等于"projects"
。 你可以在irb中尝试这个:
>> "projects" || "parts" => "projects"
你想做的是
if ["projects", "parts"].include? @controller.controller_name
不同之处在于发生的事情的顺序。 还有|| 没有做你认为它在2和3中做的事情。
你也可以这样做
if ['projects','parts'].include?(@controller.controller_name)
如果您需要添加更多匹配项,请在将来减少代码。
||
也是一个空的合并运算符,所以
"projects" || "parts"
将返回第一个非null的字符串(在本例中为“projects”),这意味着在后两个示例中,您将始终在评估:
if @controller.controller_name == "projects"
解雇irb,您可以检查是否发生了这种情况:
a = "projects" b = "parts" a || b
返回projects
基本上,==不会分配给其他运营商。 3 * (2+1)
与3 * 2 + 3 * 1
相同的原因是乘法在加法上分布。
||的值 表达式将是其论据之一。 因此第二个陈述相当于:
if @controller.controller_name == "projects"
|| 优先级低于==,因此第3个语句相当于:
if (@controller.controller_name == "projects") || "ports"
那里有几件不同的事情:
if @controller.controller_name == "projects" || @controller.controller_name == "parts"
这给出了我想要的行为。 逻辑非常基本:如果控制器名称是“projects”或“parts”,则返回true
另一种方法是:
if ["projects", "parts", "something else..."].include? @controller.controller_name
这将检查控制器名称是否在列表中的某个位置。
现在换其他例子:
if @controller.controller_name == ("projects" || "parts")
这不会做你想要的。 它将首先评估("projects" || "parts")
(这将导致“项目”),然后只检查控制器名称是否等于那个。
if @controller.controller_name == "projects" || "parts"
这个甚至更加狡猾。 这总是会导致真实的。 它将首先检查控制器名称是否等于“projects”。 如果是,则语句的计算结果为true。 如果没有,它会自行评估“部分”:在ruby中也会评估为“true”(出于布尔逻辑的目的,任何非零对象都被视为“true”)
获得非详细解决方案的简单方法是
if ["a", "b", "c"].include? x
这实际上与||
无关 而是在ruby中被认为是真实的价值。 一切都是假的,零是真的。
逻辑或运算符|| 适用于布尔表达式,因此在字符串上使用它不会做你想要的。
有几种方法可以实现您想要的更简洁,更易读的内容。
使用Array #include? 和一个简单的if语句:
if ["projects", "parts"].include? @controller.controller_name do_something else do_something_else end
使用案例陈述:
case @controller.controller_name when "projects", "parts" then do_something else do_something_else end
第一个将“projects”和“parts”字符串文字与@controller.controller_name
变量进行比较。
第二个评估(“projects”||“parts”),这是“项目”,因为“projects”字符串文字既不是false
也不是nil
或空字符串,并将它与@controller.controller_name
进行比较
第三个比较@controller.controller_name
和“projects”,如果它们相等,则返回true
,如果不是,则返回“parts”,对于if
语句,返回等于true
。