Ruby 如果| |的优先级高于=,那么为什么'a | | a=b'起作用?
我理解Ruby 如果| |的优先级高于=,那么为什么'a | | a=b'起作用?,ruby,Ruby,我理解|和或或&和和之间的区别,但我不理解的是: 考虑一个返回@var值的方法,如果@var为nil表示false,则对其进行初始化 由于我来自JavaScript背景,我会这样写,因为|的优先级高于=: def some_method @var || (@var = MyClass.new) end 或者使用或,因为或的优先级较低: def some_method @var or @var = MyClass.new end 或者更简洁地说: def some_method @
|
和或或&
和和之间的区别,但我不理解的是:
考虑一个返回@var
值的方法,如果@var
为nil表示false,则对其进行初始化
由于我来自JavaScript背景,我会这样写,因为|
的优先级高于=
:
def some_method
@var || (@var = MyClass.new)
end
或者使用或
,因为或
的优先级较低:
def some_method
@var or @var = MyClass.new
end
或者更简洁地说:
def some_method
@var ||= MyClass.new
end
但碰巧这个版本也能工作:
def some_method
@var || @var = MyClass.new
end
我在网上搜索,但没有找到有用的结果
他们中的大多数人只是说出了|
和或之间的区别
运算符优先级表明确指出,|
的优先级高于=
我甚至可以做a=b | | c=d
,Ruby认为这是a=(b | |(c=d))
这种行为是在某处记录的还是Ruby中的某种魔力
p.S.CoffeeScript也有同样的行为
更新/澄清:此问题与短路评估无关。但是关于运算符优先级。请让我再说一遍:
如果| |
的优先级高于=
,那么为什么ruby将a | | a=b
视为a | |(a=b)
,而不是(a | a)=b
,并引发语法错误?短路求值法
。只有当第一个参数不足以计算表达式时,才会考虑第二个参数
在您的示例中,由于@var
最初是nil
,表达式的后半部分将被计算并设置为MyClass.new
的实例
这些表达式的扩展非常有趣。有几篇博文很好地介绍了这一点。Ruby使用所谓的短路求值来求值这样的逻辑表达式。只有当第一个参数不足以计算表达式时,才会考虑第二个参数
在您的示例中,由于@var
最初是nil
,表达式的后半部分将被计算并设置为MyClass.new
的实例
这些表达式的扩展非常有趣。有几篇博文很好地介绍了它。我会完全忘记和和或。只要使用&&
和| |
,如果需要,可以使用括号
上一个示例之所以有效,是因为您使用的是实例变量。考虑一下这里的差异:
1.9.3> newvar
NameError: undefined local variable or method `newvar' for main:Object
from (irb):59
from /home/don/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'
1.9.3> @newvar
=> nil
1.9.3>newvar
NameError:未定义的局部变量或main:对象的“newvar”方法
来自(irb):59
from/home/don/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in`'
1.9.3>@newvar
=>零
如果尝试newvar | | newvar=3
,则会引发错误
你可能想看看这个问题:。我会完全忘记和和或。只要使用&&
和| |
,如果需要,可以使用括号
上一个示例之所以有效,是因为您使用的是实例变量。考虑一下这里的差异:
1.9.3> newvar
NameError: undefined local variable or method `newvar' for main:Object
from (irb):59
from /home/don/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'
1.9.3> @newvar
=> nil
1.9.3>newvar
NameError:未定义的局部变量或main:对象的“newvar”方法
来自(irb):59
from/home/don/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in`'
1.9.3>@newvar
=>零
如果尝试newvar | | newvar=3
,则会引发错误
您可能想看看这个问题:。只有当表达式中存在歧义时,优先级才会成为问题。在下列情况下:
@var || @var = MyClass.new
没有含糊不清的地方。赋值运算符=
只有在左侧有一个变量时才有意义(忽略多个赋值引起的复杂性)。为名为“@var | |@var
”的变量赋值是没有意义的。因此,不存在歧义。解释上述表达式的唯一方法是将其解释为:
@var || (@var = MyClass.new)
因此,优先级在这里不是问题。只有当表达式中存在歧义时,优先级才会成为问题。在下列情况下:
@var || @var = MyClass.new
没有含糊不清的地方。赋值运算符=
只有在左侧有一个变量时才有意义(忽略多个赋值引起的复杂性)。为名为“@var | |@var
”的变量赋值是没有意义的。因此,不存在歧义。解释上述表达式的唯一方法是将其解释为:
@var || (@var = MyClass.new)
因此,优先级在这里不是问题。我不知道答案,但确实让我想到了一个旧的LPC错误,您可以在那里编写!a=1
。也许你也应该试试。这里的答案是短路。@PerJohansson!a=1
在Ruby中工作a
变为1,表达式的计算结果为false,带有一个警告:found=in conditional,should=
我不知道答案,但确实让我想到了一个可以编写的旧LPC错误!a=1
。也许你也应该试试。这里的答案是短路。@PerJohansson!a=1
在Ruby中工作a
变为1,表达式的计算结果为false,带有一个warning:found=in conditional,应该是==
对不起,这没有回答我的问题。尝试将newvar
初始化为nil,然后将newvar | | newvar=42
。它的效果与放置newvar=newvar | | 42
相同。请看我添加到这个问题的澄清。好的,澄清中你的问题的答案是短路,就像其他人所说的。我只是说,你上次