【问题标题】:'||=' operator in Ruby'||=' Ruby 中的运算符
【发布时间】:2012-01-20 07:58:39
【问题描述】:

有人可以向我解释以下 Ruby 代码的含义吗? (我在一个人的项目中看到了这段代码sn-p):

car ||= (method_1 || method_2 || method_3 || method_4)

上面的代码和下面的代码有什么区别?

car = method_1 || method_2 || method_3 || method_4

---------更新-------------

好的,在阅读@Dave 的解释后,我明白了||= 运算符的含义,我的下一个问题method_2method_3method_4 是否都返回一个值,哪个是值将分配给car? (我想car 最初是nil

【问题讨论】:

标签: ruby


【解决方案1】:

这是一个“条件赋值”的赋值运算符

看这里->http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Operators

条件赋值:

 x = find_something() #=>nil
 x ||= "default"      #=>"default" : value of x will be replaced with "default", but only if x is nil or false
 x ||= "other"        #=>"default" : value of x is not replaced if it already is other than nil or false

运算符 ||= 是表达式的简写形式:

x = x || "default" 

编辑:

看过OP的编辑后,例子只是这个的延伸,意思是:

car = method_1 || method_2 || method_3 || method_4

将 method_1、method_2、method_3、method_4 的第一个非 nil 或非 false 返回值(按此顺序)分配给 car,否则将保留其旧值。

【讨论】:

  • 你的解释和其他人有点不同,但我很喜欢你的解释,因为你指出了使用这个运算符的关键点(条件赋值)。虽然如果您还可以提及 x||= Y 等于 x=x||y 会更好
  • 请检查我的更新,我有一个关于运营商的新问题。
  • 嘿,很高兴我的帮助 - 我已经编辑了我的答案,添加了一些额外内容 - 希望它能解决你的第一条评论和你的问题更新。
  • @Dave,你有没有在我的帖子中检查过我的更新,我有一个新问题,在阅读你的答案后产生。一般来说,我想知道如果几个方法返回值,哪个值将分配给左侧变量?这是什么规则?
  • 谢谢戴夫。我得到了我想知道的。
【解决方案2】:
car ||= (method_1 || method_2) 

等价于

car = (car || (method_1 || method_2)) 

一般来说,

x op= y 

意思

x = x op y

【讨论】:

  • @Leem.fin:你也看到了我的编辑。 car ||= anything 表示car = car || anything
  • 哦!我知道了。我以为它会'||'与“=”符号右侧部分的所有可能组合,这就是我添加更多方法的原因。
  • @Armen,你觉得@Dave 的解释怎么样
  • Dave 展示了 ||= 运算符的实际作用:一旦在第一行调用了它,x 就包含一个“非假”值,而第二行什么也不做。
  • -1。这是错误的。 a ||= b 更像a || a = b 而不是a = a || b,尽管它实际上并不等同于其中一个
【解决方案3】:

||= 运算符首先检查您的值 car 是否已设置。如果car返回nil,它将分配右侧第一个不返回nilfalse的值。

因此,鉴于上面的示例,如果您将值分配给 car like

car = "BMW"

你执行你的code-sn-p,car的值还是“BMW”;

如果method_1返回(例如)字符串"Value from Method 1"并且汽车是nilfalse,那么汽车这个字符串将被分配给汽车

car = nil
car ||= (method_1 || method_2)
car # => "Value from Method 1"

如果 method_1 也返回 nil/false,它将检查 method_2 中的值,依此类推,直到获得某种真值

与您的第二个代码-sn-p 的区别在于,在 ||= 的情况下,将首先评估变量 car,并设置它是否返回 nil 或 false。

如果您只使用=,则不会进行评估,并且 car 将设置为右侧第一个不返回 nil 或 false 的值。

-- 更新--

为了回答您的更新问题,右侧的值将从左到右进行评估,因此将分配第一个不返回 nilfalse 的值。

car = nil
# method_1 => "nil"
# method_2 => "false"
# method_3 => "value method 3"
# method_4 => "I won't be called"

car ||= (method_1 || method_2 || method_3 || method_4)
# => "value method 3"

【讨论】:

    【解决方案4】:
    car ||= (method_1 || method_2 || method_3 || method_4)  
    

    如果 car 最初不是 nil,则在运行此语句后,car 将保留其值。

    如果 car 在此语句之前为 nil,则从 method_1、method_2、... 返回的第一个非 nil 值将分配给 car。


    car = method_1 || method_2 || method_3 || method_4
    

    在这种情况下,car 将被重新分配第一个非 nil 值以从方法中返回,即使在此语句运行之前 car 已经具有非 nil 值

    【讨论】:

      【解决方案5】:

      汽车 ||= (method_1 || method_2)

      等于

      汽车=汽车|| (方法_1 || 方法_2)

      【讨论】:

      • -1。这是错误的。 a ||= b 更像a || a = b 而不是a = a || b,尽管它实际上并不等同于其中一个
      【解决方案6】:

      简而言之,它等于:

      car = car || method_1 || method_2
      

      更详细地说,它有点复杂:

      car = (defined?(car) && car) || (method_1 || method_2)
      

      在任何情况下,||= 之后的内容将car 时执行:

      • 尚未定义
      • false
      • nil

      【讨论】:

        【解决方案7】:

        回答更新:

        method_2 被赋值,因为它是列表中的第一个非 false、非 nil 值。

        【讨论】:

          猜你喜欢
          • 2010-10-31
          • 1970-01-01
          • 2012-11-06
          • 1970-01-01
          • 2022-12-21
          • 1970-01-01
          • 2021-12-04
          • 2011-01-16
          • 2011-03-02
          相关资源
          最近更新 更多