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

时间:2011-05-07 16:12:37

标签: ruby arrays slice parallel-assignment

下面的两个代码片段应该打印相同的东西,但它们不会。

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)

1 个答案:

答案 0 :(得分:4)

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

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

A, B = C, D

相当于

A = C
B = D

所以你做的第一件事就是......

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

两种情况。所以现在是

["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"]
相关问题