@foo ||是什么@foo =“ bar”在Ruby中意味着什么,为什么?

时间:2019-02-02 04:48:12

标签: ruby

@foo || @foo = "bar"在Ruby中是什么意思?对我来说,它似乎具有@foo || (@foo = "bar")而不是(@foo || @foo) = "bar"的含义。但是,这与|| has a higher precedence than = in Ruby的事实相矛盾。

我知道Ruby中的||是短路运算符。我也了解,||将根据优先级在=之前进行评估。我不了解的是@foo = "bar"似乎是||的正确操作。根据{{​​3}},||的正确操作符应为@foo,并且表达式应等效于(@foo || @foo) = "bar",这是非法的。

3 个答案:

答案 0 :(得分:1)

Ruby使用Short-circuit evaluation,因此它评估第一个参数以确定是否应该继续第二个参数。

@foo || @foo = "bar"的情况下,执行OR操作的方式是,当发现第一个参数为nil时,将评估第二个参数,这是赋值语句。如果找到第一个参数,则它将忽略第二个参数(在这种情况下为语句) 请注意,它不只是为@foo分配值,而是在分配后完成逻辑语句的返回值。

如果您写的话,先执行@foo = @foo || 'sd'逻辑运算然后分配。

答案 1 :(得分:1)

我想到底它确实是简单的短路评价为射线在他的回答中提到,但我认为文档是缺乏这方面。

||是短路运算符,因此评估从左向右进行,一旦找到真,就完成评估并返回true,否则将向右进行

modifier-if(也在链接到的页面上列出)的优先级比赋值=低,但是赋值不是短路运算符,因此类似

的代码
foo = "not set"
is_true = false
foo = 42 if is_true
puts foo 

将打印

  
    

未设置

  

while代码,例如:

foo = "not set"
is_true = true 
foo = 42 if is_true 
puts foo 

将打印

  
    

42

  

||是短路运算符,因此这样的代码:

foo = 0 
foo || foo = 42
puts foo 

将打印

  
    

0

  

因为左手foo不为零,所以没有理由评估右手。

而这样的代码:

foo = nil
foo || foo = 42
puts foo 

将打印

  
    

42

  

由于foo为零,因此评估将继续在||的右侧,直到其为true或返回最后一个表达式为true或false为止。

但是我同意您指向的文件暗示

x || y = z应该基于优先级,可以解释为(x || y) = z,这是不合法的。但是,很明显,这与尝试为布尔值分配值相同。

例如:

(true || true) = 42 

是语法错误

与之一样:

a = nil
b = nil
(a || b) = 42

a = nil
b = nil 
a || b = 42
puts b

结果

  

42

答案 2 :(得分:0)

简单来说,您对优先规则的解释是错误的。

优先规则在存在歧义时适用。使用赋值语法时,=的左侧必须是单个标记,该标记作为常量或某种类型的变量才是合法的。

@foo || @foo = ...

只能解释为

@foo || (@foo = ...)

并且这里没有歧义,因此没有优先级问题。

优先规则所关注的是=的右侧。就是说

@foo = bar || baz

解释为

@foo = (foo || baz)

不是

(@foo = foo) || baz