为什么我可以将一个子数组传递给 `Array#each` 方法?

3
我理解每个each都会将数组中的每一个元素传递给块。在下面的例子中,应该是数组中的每个元素为[1,2][3,4],而不是1234
arr = [[1,2], [3,4]]
arr.each {|item1, item2| puts " #{item1} #{item2} "}
#  1 2
#  3 4
# => [[1, 2], [3, 4]]

为什么以下内容有效?
arr.each {|item| puts item}
# 1
# 2
# 3
# 4
# => [[1,2], [3,4]]

这是 Ruby 的一个特性,叫做解构。 - sschmeck
2
此外,您需要了解如何使用数组进行输出。当传递一个数组给puts时,它会将每个项目单独打印在一行上,这就是为什么输出看起来像那样的原因。它只迭代两次,但由于puts输出的原因,看起来像迭代了4次。 - engineersmnky
1
尝试将 puts item 替换为 p item - Cary Swoveland
1个回答

3

实际上,通过 each 传递给块的元素是 [1, 2][3, 4] 等,而不是 12 等。当(块)变量赋值中参数数量不匹配时,会尝试解构数组以使它们匹配。在您的情况下,相当于:

item1, item2 = [1, 2]

右侧的参数比左侧的参数少。所以右侧的数组被解构为:

item1, item2 = 1, 2

您可以明确地将其写为:

{|(item1, item2)| ...}

但是这里的括号可以省略:
{|item1, item2| ...}

这里所解释的特性在 Ruby 中被称为并行赋值。 - Raman
2
不完全是。这不是赋值,而是参数绑定。然而,在早期版本的Ruby中,块的参数绑定使用了赋值语义。现在不再这样做了,但为了方便和向后兼容性,保留了一些功能,包括数组解构。试想一下,如果没有解构,就必须使用Hash#each - Jörg W Mittag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接