ruby 中的并行分配对于两个等效代码片段的工作方式不同

发布于 2024-11-05 19:48:10 字数 746 浏览 2 评论 0原文

下面的两个代码片段应该打印相同的内容,但事实并非如此。

ary = %W(1 2 5 6 B 8 5 4 6 5 6 9 7 A)
indx1 = 0...ary.index("B")
indx2 = (ary.index("A") + 1)..-1
ary[indx1], ary[indx2] = ary[indx2], ary[indx1]
puts ary.inspect

ary = %W(1 2 5 6 B 8 5 4 6 5 6 9 7 A)
ary[0...ary.index("B")], ary[(ary.index("A") + 1)..-1] = ary[(ary.index("A") + 1)..-1],  ary[0...ary.index("B")]
puts ary.inspect

第一个打印:

["B", "8", "5", "4", "6", "5", "6", "9", "7", "A", nil, nil, nil, nil, "1", "2", "5", "6"]

第二个:

["B", "8", "5", "4", "6", "5", "6", "9", "7", "A", "1", "2", "5", "6"]

他们不应该打印相同的东西吗?他们似乎与我相当。

(使用 Mac OSX 10.6.7 和 ruby​​ 1.9.2-p180)

The two code fragments below should print the same thing, but they don't.

ary = %W(1 2 5 6 B 8 5 4 6 5 6 9 7 A)
indx1 = 0...ary.index("B")
indx2 = (ary.index("A") + 1)..-1
ary[indx1], ary[indx2] = ary[indx2], ary[indx1]
puts ary.inspect

ary = %W(1 2 5 6 B 8 5 4 6 5 6 9 7 A)
ary[0...ary.index("B")], ary[(ary.index("A") + 1)..-1] = ary[(ary.index("A") + 1)..-1],  ary[0...ary.index("B")]
puts ary.inspect

The first prints:

["B", "8", "5", "4", "6", "5", "6", "9", "7", "A", nil, nil, nil, nil, "1", "2", "5", "6"]

and the second:

["B", "8", "5", "4", "6", "5", "6", "9", "7", "A", "1", "2", "5", "6"]

Shouldn't they print the same thing? They seem equivalent to me.

(Using Mac OSX 10.6.7 and ruby 1.9.2-p180)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

-柠檬树下少年和吉他 2024-11-12 19:48:10

它们是不同的,因为在第一种情况下,您预先计算索引,而在第二种情况下,您动态计算它们,并且数组在第一个分配和第二个分配之间变化。

从技术上讲,两个 RHS 评估都是在 LHS 分配之前进行的,但是两个 LHS 分配不能同时进行,因此在这种情况下,您实际上看到的

A, B = C, D

是相当于

A = C
B = D

所以您要做的第一件事是......

ary[0...ary.index("B")] = ary[(ary.index("A") + 1)..-1]

在这两种情况下。所以 ary 现在是

["B", "8", "5", "4", "6", "5", "6", "9", "7", "A"]

现在最初您将 indx1 和 indx2 分别计算为 0...414..-1 ,但现在如果您重新计算 indx1 和 indx2你将拥有的值:

indx1 = 0...ary.index("B")       #=> 0...0
indx2 = (ary.index("A") + 1)..-1 #= 10..-1

换句话说,

ary[indx2] = ary[indx1]

不再等于

ary[(ary.index("A") + 1)..-1] = ary[0...ary.index("B")]

也就是说,

ary = ["B", "8", "5", "4", "6", "5", "6", "9", "7", "A"]
ary[(ary.index("A") + 1)..-1] = ary[0...ary.index("B")]

给你

ary #=> ["B", "8", "5", "4", "6", "5", "6", "9", "7", "A"]

同时

ary = ["B", "8", "5", "4", "6", "5", "6", "9", "7", "A"]
ary[indx2] = ary[indx1]

给你

ary #=> ["B", "8", "5", "4", "6", "5", "6", "9", "7", "A", nil, nil, nil, nil, "1", "2", "5", "6"]

They're different because in the first case you're pre-calculating the indices, while in the second you're calculating them dynamically, and the array changes between the first assignment and the second.

Technically both RHS evaluations are made before the LHS assignments are made, but both LHS assignments can't be made simultaneously, so in this case you're effectively seeing that

A, B = C, D

is equivalent to

A = C
B = D

So the first thing you do is...

ary[0...ary.index("B")] = ary[(ary.index("A") + 1)..-1]

in both cases. So ary is now

["B", "8", "5", "4", "6", "5", "6", "9", "7", "A"]

Now originally you'd calculated indx1 and indx2 as 0...4 and 14..-1 respectively, but now if you recalculated the indx1 and indx2 values you'd have:

indx1 = 0...ary.index("B")       #=> 0...0
indx2 = (ary.index("A") + 1)..-1 #= 10..-1

In other words,

ary[indx2] = ary[indx1]

is no longer equivalent to

ary[(ary.index("A") + 1)..-1] = ary[0...ary.index("B")]

That is,

ary = ["B", "8", "5", "4", "6", "5", "6", "9", "7", "A"]
ary[(ary.index("A") + 1)..-1] = ary[0...ary.index("B")]

gives you

ary #=> ["B", "8", "5", "4", "6", "5", "6", "9", "7", "A"]

while

ary = ["B", "8", "5", "4", "6", "5", "6", "9", "7", "A"]
ary[indx2] = ary[indx1]

gives you

ary #=> ["B", "8", "5", "4", "6", "5", "6", "9", "7", "A", nil, nil, nil, nil, "1", "2", "5", "6"]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文