书中很好的解释:The Ruby Programming Language
4.5.5.6。并行赋值中的括号
并行赋值最难理解的特性之一是左侧可以使用括号来表示“子赋值”。如果一组两个或多个左值括在括号中,则最初将其视为单个左值。一旦确定了相应的右值,就会递归地应用并行赋值规则——将该右值分配给括号中的左值组。考虑以下分配:
x,(y,z) = a, b
这实际上是同时执行的两个任务:
x = a
y,z = b
但请注意,第二个作业本身就是一个并行作业。因为我们在左侧使用了括号,所以执行了递归并行赋值。为了让它工作,b 必须是一个可分解的对象,例如数组或枚举器。
这里有一些具体的例子可以使这一点更清楚。请注意,左侧的括号用于“解包”右侧的一层嵌套数组:
x,y,z = 1,[2,3] # No parens: x=1;y=[2,3];z=nil
x,(y,z) = 1,[2,3] # Parens: x=1;y=2;z=3
a,b,c,d = [1,[2,[3,4]]] # No parens: a=1;b=[2,[3,4]];c=d=nil
a,(b,(c,d)) = [1,[2,[3,4]]] # Parens: a=1;b=2;c=3;d=4
现在来到你的第一个困惑:
a,(b,c),d = 1,2,3,4 # a=1, b=2,c=nil, d=3
为什么 d=3 而 c=nil?
这是因为a,(b,c),d = 1,2,3,4
实际上如下:
a = 1
(b,c) = 2
d = 3
第二个困惑:
a,(b,c),d = 1,[2,3],4 # a=1, b=2,c=3, d=4
c=3 和 d=4?
这是因为a,(b,c),d = 1,[2,3],4
实际上如下:
a = 1
(b,c) = [2,3]
d = 4