gpt4 book ai didi

arrays - block 变量的括号规则

转载 作者:数据小太阳 更新时间:2023-10-29 09:03:12 26 4
gpt4 key购买 nike

我在阅读 The Ruby Way 时遇到了以下代码:

class Array
def invert
each_with_object({}).with_index { |(elem, hash), index| hash[elem] = index }
end
end

我想确保我理解括号在 (elem, hash) 中的作用。

第一个方法 (each_with_object({})) 将产生两个对象给 block 。第一个对象将是数组中的元素;第二个对象将是散列。括号确保将这两个对象分配给不同的 block 变量。如果我改为使用 { |elem, index} #code } ,则 elem 将是一个由元素和散列组成的数组。我认为这很清楚。

我的困惑在于,如果我不链接这两个方法,我就不必使用括号,而是可以使用:each_with_object({}) { |elem, obj #code }

block 变量中何时需要括号的规则是什么?为什么它们在此处的两个示例之间有所不同?我的简单解释是,当方法没有链接时,yield 代码看起来像 yield (elem, obj),但是当方法被链接时,代码看起来像像 yield([elem, obj], index)。 (我们可以推测,如果我们链接第三个方法,则会传入第二个数组)。这样对吗?从最后一个链接方法传入的对象不是数组吗?

我想问题不是所有这些猜想,而是归结为:“当链接接受 block 的方法时,yield 语句是什么样的?

最佳答案

您的问题仅与 block 和 block 变量无关。相反,它涉及“消除歧义”数组的规则。

让我们考虑一下您的示例:

[1,2,3].each_with_object({}).with_index {|(elem, hash), index| hash[elem] = index}

我们有:

enum0 = [1,2,3].each_with_object({})
#=> #<Enumerator: [1, 2, 3]:each_with_object({})>

我们可以通过将其转换为数组来查看此枚举器的元素:

enum0.to_a
#=> [[1, {}], [2, {}], [3, {}]]

接下来我们有:

enum1 = enum0.with_index
#=> #<Enumerator: #<Enumerator: [1, 2, 3]:each_with_object({})>:with_index>
enum1.to_a
#=> [[[1, {}], 0], [[2, {}], 1], [[3, {}], 2]]

您可能想将 enum1 视为“复合枚举器”,但它只是一个枚举器。

您看到 enum1 具有三个元素。这些元素由 Enumerator#each 传递给 block .第一个是:

enum1.first
#=> [[1, {}], 0]

如果我们有一个单独的 block 变量,比如a,那么

a #=> [[1, {}], 0]

我们可以使用“消除歧义”以不同的方式分解它。例如,我们可以这样写:

a,b = [[1, {}], 0]
a #=> [1, {}]
b #=> 0

现在让我们找出所有的元素:

a,b,c = [[1, {}], 0]
a #=> [1, {}]
b #=> 0
c #=> nil

糟糕!那不是我们想要的。我们刚刚经历了“消歧义”中的“歧义”。我们需要这样写,以便我们的意图明确。我们通过添加括号来做到这一点。通过这样做,您是在告诉 Ruby,“将这个位置的数组分解为其组成元素”。我们有:

(a,b),c = [[1, {}], 0]
a #=> 1
b #=> {}
c #=> 0

消除歧义非常有用。例如,假设一个方法返回数组:

[[1,[2,3],[[4,5],{a: 6}]],7]

我们希望提取所有的个体值。我们可以这样做:

(a,(b,c),((d,e),f)),g = [[1,[2,3],[[4,5],{a: 6}]],7]
a #=> 1
b #=> 2
c #=> 3
d #=> 4
e #=> 5
f #=> {:a=>6}
g #=> 7

同样,您只需要记住括号的意思是“将这个位置的数组分解为其组成元素”。

关于arrays - block 变量的括号规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30326964/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com