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
||的确切语义 是:
所以你的第一个表达式是,如果@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)
不同之处在于发生的事情的顺序.还有|| 没有做你认为它在2和3中做的事情.
你也可以
if ['projects','parts'].include?(@controller.controller_name)
Run Code Online (Sandbox Code Playgroud)
如果您需要添加更多匹配项,请在将来减少代码.
|| 也是一个空的合并运算符,所以
"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
那里发生了一些不同的事情:
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””)