理解"||" 在Ruby中的if条件中的OR运算符

ste*_*ble 37 ruby if-statement operators

简而言之,为什么以下三条线的影响不一样?

if @controller.controller_name == "projects" || @controller.controller_name == "parts"

if @controller.controller_name == ("projects" || "parts")

if @controller.controller_name == "projects" || "parts"
Run Code Online (Sandbox Code Playgroud)

第一个给出了我想要的结果,但实际上有更多选项而不仅仅是项目和部分,使用该表单创建了一个详细的语句.另外两个更紧凑,但不会给我相同的结果.

Mar*_*llo 57

||的确切语义 是:

  • 如果第一个表达式不是nil或false,则返回它
  • 如果第一个表达式为nil或false,则返回第二个表达式

所以你的第一个表达式是,如果@controller.controller_name == "projects",则表达式短路并返回true.如果没有,它会检查第二个表达式.第二和第三个变种基本上if @controller.controller_name == "projects",因为"projects" || "parts"平等"projects".你可以在irb中尝试这个:

>> "projects" || "parts"
=> "projects"
Run Code Online (Sandbox Code Playgroud)

你想做的是

if ["projects", "parts"].include? @controller.controller_name
Run Code Online (Sandbox Code Playgroud)


Jim*_*Jim 7

不同之处在于发生的事情的顺序.还有|| 没有做你认为它在2和3中做的事情.

你也可以

if ['projects','parts'].include?(@controller.controller_name)
Run Code Online (Sandbox Code Playgroud)

如果您需要添加更多匹配项,请在将来减少代码.


jer*_*ith 6

|| 也是一个空的合并运算符,所以

"projects" || "parts"
Run Code Online (Sandbox Code Playgroud)

将返回第一个非null的字符串(在本例中为"projects"),这意味着在后两个示例中,您将始终在评估:

if @controller.controller_name == "projects"
Run Code Online (Sandbox Code Playgroud)

解雇irb,您可以检查是否发生了这种情况:

a = "projects"
b = "parts"

a || b
Run Code Online (Sandbox Code Playgroud)

回报 projects

  • 实际上,`或'两个字符串在一起会给你第一个字符串,以支持成语,如`a || ="hello"`和`a = somefunc()|| default` (4认同)

mad*_*lep 6

那里发生了一些不同的事情:

if @controller.controller_name == "projects" || @controller.controller_name == "parts"
Run Code Online (Sandbox Code Playgroud)

这给出了您想要的行为。逻辑很基本:如果控制器名称是“ projects”或“ parts”,则返回true

另一种方法是:

if ["projects", "parts", "something else..."].include? @controller.controller_name
Run Code Online (Sandbox Code Playgroud)

这将检查控制器名称是否在列表中。

现在来看其他示例:

if @controller.controller_name == ("projects" || "parts")
Run Code Online (Sandbox Code Playgroud)

这不会做你想要的。它将("projects" || "parts")首先进行评估(这将导致“项目”),然后将仅检查控制器名称是否与此相等。

if @controller.controller_name == "projects" || "parts"
Run Code Online (Sandbox Code Playgroud)

这变得更加古怪。这将始终为真。首先将检查控制器名称是否等于“ projects”。如果是这样,则该语句评估为true。如果不是这样,它将自行评估“部分”:红宝石也将评估为“ true”(出于布尔逻辑的目的,任何非nil对象均被视为“ true””)