为什么无法使用 Ruby 中的 each do 循环填充数组?
Why is it not possible to fill an array using an each do loop in Ruby?
如果我使用每个 do 循环来填充一个数组,它将保持数组原样(在本例中它将是一个大小为 4 的 nil 数组)
array = Array.new(4)
array.each do |i|
i = 5
end
我知道我可以使用 array = Array.new(4) {desired value}
用我想要的值初始化一个数组,但在某些情况下我会在不同的值之间进行选择,并且我试图了解每个 do 循环是如何工作的。
我目前的做法是用我想要的值填充数组
array = Array.new(4)
array.each_with_index do |val, i|
array[i] = 5
end
解决方案
你需要:
array = Array.new(4) do |i|
5
# or some logic depending on i (the index between 0 and 3)
end
您的代码
array = Array.new(4)
数组现在是一个包含 4 个元素的数组(每次 nil
)。
array.each
迭代这 4 个元素(仍然是 nil
),并将 i
设置为等于 nil
.
的块局部变量
在此块中,您用 5 覆盖了 i
,但您不对其进行任何操作。在下一次迭代中,i
被设置回 nil
,然后是 5
,依此类推...
您不更改原始数组,您只更改已设置为等于数组元素的局部变量。
区别在于
i = 5
是一项作业。它将值 5
赋给变量 i
.
在Ruby中,赋值只影响局部作用域,它们不会改变调用者作用域中的变量:
def change(i)
i = 5 # <- doesn't work as you might expect
end
x = nil
change(x)
x #=> nil
因此不可能通过分配给变量来用另一个对象替换数组元素。
另一方面,
array[i] = 5
不是赋值,而是伪装的方法调用。相当于:
array.[]=(i, 5)
或
array.public_send(:[]=, i, 5)
它要求数组将索引 i
处的元素设置为 5
。
如果我使用每个 do 循环来填充一个数组,它将保持数组原样(在本例中它将是一个大小为 4 的 nil 数组)
array = Array.new(4)
array.each do |i|
i = 5
end
我知道我可以使用 array = Array.new(4) {desired value}
用我想要的值初始化一个数组,但在某些情况下我会在不同的值之间进行选择,并且我试图了解每个 do 循环是如何工作的。
我目前的做法是用我想要的值填充数组
array = Array.new(4)
array.each_with_index do |val, i|
array[i] = 5
end
解决方案
你需要:
array = Array.new(4) do |i|
5
# or some logic depending on i (the index between 0 and 3)
end
您的代码
array = Array.new(4)
数组现在是一个包含 4 个元素的数组(每次 nil
)。
array.each
迭代这 4 个元素(仍然是 nil
),并将 i
设置为等于 nil
.
在此块中,您用 5 覆盖了 i
,但您不对其进行任何操作。在下一次迭代中,i
被设置回 nil
,然后是 5
,依此类推...
您不更改原始数组,您只更改已设置为等于数组元素的局部变量。
区别在于
i = 5
是一项作业。它将值 5
赋给变量 i
.
在Ruby中,赋值只影响局部作用域,它们不会改变调用者作用域中的变量:
def change(i)
i = 5 # <- doesn't work as you might expect
end
x = nil
change(x)
x #=> nil
因此不可能通过分配给变量来用另一个对象替换数组元素。
另一方面,
array[i] = 5
不是赋值,而是伪装的方法调用。相当于:
array.[]=(i, 5)
或
array.public_send(:[]=, i, 5)
它要求数组将索引 i
处的元素设置为 5
。