【问题标题】:Understanding the "||" OR operator in If conditionals in Ruby理解“||” Ruby 中 If 条件中的 OR 运算符
【发布时间】:2010-12-05 23:25:42
【问题描述】:

简单来说,为什么下面三行的影响不一样?

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

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

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

第一个给了我想要的结果,但实际上除了项目和部分之外还有更多的选项,使用该表单会创建一个冗长的语句。其他两个更紧凑,但不要给我相同的结果。

【问题讨论】:

    标签: ruby operators if-statement


    【解决方案1】:

    || 的确切语义是:

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

    所以你的第一个表达式的结果是,如果@controller.controller_name == "projects",那么表达式短路并返回true。如果不是,它检查第二个表达式。第二个和第三个变体本质上是if @controller.controller_name == "projects",因为"projects" || "parts" 等于"projects"。你可以在 irb 中试试这个:

    >> "projects" || "parts"
    => "projects"
    

    你想做的是

    if ["projects", "parts"].include? @controller.controller_name
    

    【讨论】:

      【解决方案2】:

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

      你也可以这样做

      if ['projects','parts'].include?(@controller.controller_name)
      

      如果您需要添加更多匹配项,将来可以减少代码。

      【讨论】:

        【解决方案3】:

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

        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"
        

        这个变得更古怪了。这将始终导致 true。它将首先检查控制器名称是否等于“项目”。如果是这样,则该语句评估为真。如果不是,它会自行评估“部分”:在 ruby​​ 中也会评估为“真”(出于布尔逻辑的目的,任何非 nil 对象都被视为“真”)

        【讨论】:

        • 解释得很好,我喜欢使用“古怪”:)
        【解决方案4】:

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

        "projects" || "parts"
        

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

        if @controller.controller_name == "projects"
        

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

        a = "projects"
        b = "parts"
        
        a || b
        

        返回projects

        【讨论】:

        • 实际上,or 将两个字符串放在一起会给你第一个字符串,以支持像 a ||= "hello"a = somefunc() || default 这样的成语
        【解决方案5】:

        基本上,== 不会分布在其他运算符上。 3 * (2+1)3 * 2 + 3 * 1 相同的原因是乘法分布在加法之上。

        a的值||表达式将是它的参数之一。因此第二条语句相当于:

        if @controller.controller_name == "projects"
        

        ||比 == 低 precedence,所以第 3 条语句相当于:

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

        【讨论】:

          【解决方案6】:

          逻辑或运算符 ||适用于布尔表达式,因此使用 它在字符串上不会做你想要的。

          有几种方法可以实现您想要的内容,它们不那么冗长且更具可读性。

          使用数组#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
          

          【讨论】:

            【解决方案7】:

            获得非详细解决方案的简单方法是

            if ["a", "b", "c"].include? x
            

            这实际上与|| 无关,而是在 ruby​​ 中哪些值被认为是正确的。一切除了 false 和 nil 都是 true。

            【讨论】:

              【解决方案8】:

              我看到很多人更喜欢 include? 比较。

              我更喜欢使用.in? 运算符。它更简洁。而且更具可读性,因为我们不会向 数组 提问,我们会向您想问的变量提问:根据您的情况,控制器名称

              @controller.controller_name.in? ["projects", "parts"]
              

              或者,甚至更好

              @controller.controller_name.in? %w[projects parts]
              

              【讨论】:

                【解决方案9】:

                第一个将“projects”和“parts”字符串文字与@controller.controller_name 变量进行比较。

                第二个评估 ("projects" || "parts") 是 "projects",因为 "projects" 字符串文字既不是 falsenil 也不是空字符串,并将其与 @controller.controller_name 进行比较

                第三个比较@controller.controller_name 和“projects”,如果它们相等,则返回true,如果不是,则返回“parts”,即trueif 语句。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2017-03-21
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-02-27
                  • 2015-07-08
                  • 1970-01-01
                  • 2013-05-04
                  相关资源
                  最近更新 更多