Ruby on rails 在Ruby中,赋值是否在逻辑运算符之前?
我在Ruby的Ruby on rails 在Ruby中,赋值是否在逻辑运算符之前?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我在Ruby的if条件下遇到了一个奇怪的情况。下面是重现这种情况的示例代码 p1=/hello/ p2=/世界/ s=“你好,世界” 如果m1=s.match(p1)和&m2=s.match(p2) 放入“m1=#{m1}” 放入“m2=#{m2}” 结束 输出将是 m1=world m2=world 但是我期望的是m1=hello,因为&&操作符在Ruby操作符中包含了 此代码 if m1 = s.match(p1) && m2 = s.match(p2) 似乎被解释为
if
条件下遇到了一个奇怪的情况。下面是重现这种情况的示例代码
p1=/hello/
p2=/世界/
s=“你好,世界”
如果m1=s.match(p1)和&m2=s.match(p2)
放入“m1=#{m1}”
放入“m2=#{m2}”
结束
输出将是
m1=world
m2=world
但是我期望的是m1=hello
,因为&&
操作符在Ruby操作符中包含了
此代码
if m1 = s.match(p1) && m2 = s.match(p2)
似乎被解释为
if m1 = (s.match(p1) && m2 = s.match(p2))
为什么逻辑AND运算符
&&
在赋值运算符=
之前?在ruby中,几乎所有内容(请参阅注释)都返回一个值
运算符&&
返回其右侧的最后一个表达式。因此1和&3
产生3<代码>&将在第一个错误值时短路。它返回该值或最后计算的truthy表达式
||
返回其左侧的第一个表达式-因此1 | | 3
生成1<代码>| |将在第一个真实值上短路,并返回该值
检查此差异:
1 + 5 * 3 + 1
# => 17
1 + 5 && 3 + 1
# => 4
1 + 5 || 3 + 1
# => 6
这是m1=s.match(p1)和m2=s.match(p2)
s.match(p1)
=>“您好”&&
=>正确评估每件事m2=s.match(p2)
=>“世界”m1=“你好”&&“世界”
=>“世界”m2
的赋值返回用于&&
表达式“world”第二部分的值。ruby中的赋值也会返回一个值
因此,m1和m2的值都是“world”。m1=s.match(p1)和&m2=s.match(p2)
&&
比=
具有更高的优先级,因此它将首先执行下面的&&操作
s.match(p1) && m2 = s.match(p2)
=> 'hello' && m2 = 'world'
=> 'world'
它将world
分配给m2
返回m2
,即world
,然后执行下一个分配操作
m1={(s.match(p1)和&m2=s.match(p2))的输出}
m1='world'
了解
最好使用括号使其更明确
if (m1 = s.match(p1)) && (m2 = s.match(p2))
...
end
或者可以先执行赋值操作
m1 = s.match(p1)
m2 = s.match(p2)
if m1 && m2
...
end
仅使用代码中的优先规则:
if m1 = (s.match(p1) && m2) = s.match(p2)
由于=
具有从右到左的关联性,因此在尝试执行以下操作时会出现语法错误:
(s.match(p1) && m2) = s.match(p2)
“一切都返回一个值”——表达式确实如此。但是Ruby也有类似于
break
、next
、modifier-if
、或者return
本身的语句,这些语句没有返回值。(尝试将它们用作值会导致语法错误)if
在满足条件时返回其正文,否则返回nil
<代码>返回返回nil
。是的,我认为break
和next
确实没有返回,并且=return
将导致语法错误。除此之外,几乎所有东西都会返回一个值。此外,您还可以在作业中使用=if
,只要它是以结尾关闭的。我将编辑我的答案以删除您指出的陈述。在true&&true | | false
中,“&&returns the last value to right”是什么意思?“第一个值”和“最后一个值”的表达是模糊的,因此应该避免使用。在m1=s.match(p1)和&true中,您将同意s.match(p1)
在&
之前进行评估。但是为什么呢?在答案(你的最后一段)中猜测有什么意义?读者难道不应该期望答案是确定的吗?我的答案太长,无法发表评论。我本不打算给出一个明确的答案,而是就这个问题发表了我的看法。一个问题的目的不是要引出可能的答案,直到其中一个被选为正确答案吗?我同意“第一价值”和“最后价值”是模糊的;我可能会改进这个定义和答案本身。我已经重新排列了计算顺序,因为s.match(p1)
确实是在&&
之前计算的。我认为这并不能完全解释这个问题。想想表达式(a=1&&b=2)
,它是有效的,并将2分配给a和b。如果我们看一下优先规则,这个表达式应该被解释为(a=(1&&b)=2)
,因为&&
绑定的值高于=
。但是,后者显然是错误的。@user1934428(a=1&&b=2)
将被解释为(a=(1&&b=2))
,这就是它将2分配给a和b的原因b@user1934428&&
将具有更高的优先级,因此它将检查左侧和右侧以执行该操作(a=1&&b=2)
在本例中,左侧将是1
,右侧将是b=2
。除了在本例中,a将不是1,而是2(在irb中尝试),我无法遵循您的逻辑。例如,*
的优先级高于+
,而a+x*b+y
,隐式绑定是a+(x*b)+y
。这就是更高优先级的含义。按照这个逻辑,a=1&&b=2
如果我们只观察优先级,就会有a=(1&&b)=2
。是的,因此我们不能仅用运算符优先级来解释它。我认为这也是OP提出这个问题的原因。然而,我在Ruby文档中找不到任何可以解释这种情况的东西。如果可以的话,在你的答案中包含这一点将是非常好的。你可能会觉得很有帮助。@Kaisaski:仅供参考:由于你有趣的问题没有得到令人满意的答案,我冒昧地回答了,但归结为其中的基本问题。这回答了你的问题吗?正如你所说,我认为代码会抛出一个错误。但它会返回一个意外的值。如果m1=(s.match(p1)和&m2)=s.match(p2)
显式写入,则会引发错误。但是如果m1=s.match(p1)和&m2=s.match(p2)
没有。为什么我不能得到一个错误?我在猜测(找不到任何文档)