奇怪的 ruby 字符串连接行为

Weird ruby string concat behaviour

我测试了以下代码:

irb(main):038:0> a=".";b="10"
=> "10"
irb(main):039:0> a+=b
=> ".10"
irb(main):040:0> a<<b
=> ".1010"

到目前为止一切顺利。现在让我们重复这个过程:

irb(main):042:0> a+=b+="4"
=> ".104"
irb(main):044:0> a
=> ".104"
irb(main):043:0> b
=> "104"

很好...现在将 += 替换为 <<

irb(main):045:0> a=".";b="10"
=> "10"
irb(main):046:0> a<<b<<"4"
=> ".104"
irb(main):047:0> a
=> ".104"
irb(main):048:0> b
=> "10"

如果 << 代表 += 那么为什么 b 仍然是 10 而不是 104?

If << stands for += then why b is[sic] still 10 instead of 104?

因为,当条件为假时,不管结论是什么,整句话都是真的。

P     Q     If P then Q
false false true
false true  true
true  false false
true  true  true

<<+= 不同。 x += y 基本上是 x = x + y 的缩写。这将创建一个新字符串,并将其分配给 x。例如:

> x = "hello"
> y = "world"
> old_x = x
> x += y
> x
"helloworld"
> old_x
"hello"

<< 但是实际上修改了字符串:

> x = "hello"
> y = "world"
> old_x = x
> x << y
> x
"helloworld"
> old_x
"helloworld"

这将解释您得到的差异。请注意,像 a << b << "4" 这样的做法是非常糟糕的做法,因为它在同一行上进行了两次修改。它之所以这样工作是因为 << 具有左结合性,因此它与 a<<b;a<<"4" 相同。这会将 b 附加到 a,然后将“4”附加到 a

If << stands for += then why b is still 10 instead of 104?

<< 不会 "stand for" +=。他们是做不同事情的不同运营商。

a << b << c

相同
a << b
a << c

<< 修改字符串并 returns 它,因此子表达式 (a << b) 首先计算为 a 然后 a << c 继续附加到 a 不修改 b.

另一方面:

a += b += c

相同
b = b + c
a = a + b