Ruby 按地址处理数组

Ruby 按地址处理数组,ruby,class,Ruby,Class,请帮助我了解这部分代码: class Ooo attr_accessor :class_array end def func(ctx) local_array = ctx.class_array local_array = [4,3,5,5,6] return end aaa = Ooo.new func(aaa) aaa.class_array => not [4,3,5,5,6] :-( local_array = ctx.class_array local_array

请帮助我了解这部分代码:

class Ooo
 attr_accessor :class_array
end

def func(ctx)
 local_array = ctx.class_array
 local_array = [4,3,5,5,6]
 return
end

aaa = Ooo.new
func(aaa)
aaa.class_array => not [4,3,5,5,6] :-(
local_array = ctx.class_array
local_array = [4,3,5,5,6]
我认为ruby在处理数组时使用地址。。。 为什么这个代码不起作用? 我想这样做(在C中):


为什么不跳过函数的第一行,直接这样赋值:

def func(ctx)
   ctx.class_array = [1, 2, 3, 4]
end

只需调整顺序即可:

def func(ctx)
 local_array = [4,3,5,5,6]
 ctx.class_array = local_array
 return
end

这部分代码存在问题:

class Ooo
 attr_accessor :class_array
end

def func(ctx)
 local_array = ctx.class_array
 local_array = [4,3,5,5,6]
 return
end

aaa = Ooo.new
func(aaa)
aaa.class_array => not [4,3,5,5,6] :-(
local_array = ctx.class_array
local_array = [4,3,5,5,6]
这和你想象的不一样。第二行创建一个新列表并将其分配给局部变量,从而替换对
ctx.class\u array
的引用。它不会触碰ctx.class\u阵列。一段等价的C代码也会以同样的方式工作,所以我认为这里不仅仅存在Ruby问题

在C语言中,可以使用指针来解决这个问题。在Ruby中,您可能需要:

local_array = ctx.class_array
local_array.replace [4,3,5,5,6]
或者干脆(好多了!)

顺便说一下,C程序的直接翻译也可以:

def func(ctx)
  local_array = ctx.class_array
  local_array[4] = 4
end

在您的例子中,
ctx
实例包含对
@class\u array
实例变量中数组对象的引用。在
func
方法中,将创建对同一对象的新引用,并将其指定给
local\u数组
local变量

[4,3,5,5,6]
指定给
本地_数组
时,您没有覆盖
ctx
引用的对象,而是覆盖了
本地_数组
中保存的引用,使其引用一个新数组

就指针而言,您所做的与此类似:

int array[]     = { 1, 2, 3, 4, 5 };
int new_array[] = { 4, 3, 5, 5, 6 };

int * ctx_array   = array;
int * local_array = ctx_array;

local_array = new_array; // ctx_array still points to array[0]
我认为您想要实现的是:

int ** local_array = &ctx_array;
*local_array = new_array; // ctx_array now points to the new array
这种间接操作在Ruby中是不可能的。只能通过调用对象上的方法来修改对象

但是,将C代码段转换为Ruby会生成功能完整的代码:

def func(ctx)
  local_array = ctx.class_array
  local_array[0] = 4
end

ctx.class_array[0]
 => 4

它之所以有效,是因为
local\u array
引用了与
ctx相同的对象。class\u array

为什么要使用superflous临时变量和返回?非常感谢!我明白了!我将使用“替换”than!但是,如果我想将另一个数组附加到本地数组,我应该编写什么代码呢?我的意思不仅仅是局部数组=[某物];如果我写局部数组+=另一个数组,那么ruby也会创建新的局部变量,而不是使用ctx。变量?@user1119425,因为您告诉它创建一个局部变量,然后将该局部变量分配给其他对象。@user1119425:
local\u-array+=另一个\u-array
local\u-array=local\u-array+另一个数组
相同,因此我的解释也适用于此。您可以使用
local\u array.push(*另一个\u array)
,但这很难看,这是一件好事。另外,如果这个答案对你有帮助,你也会被邀请投票并接受。是的,我知道:-)但我问“为什么这个代码不起作用?”)它不起作用,因为数组在Ruby中被指定为副本而不是指针。@Jesse:这完全错了。它们是通过引用分配的,而不是复制的。当你在方法中创建一个局部变量时就不会了……否则他的原始解决方案会起作用,不是吗?@Jesse:不会的。复制引用,然后覆盖引用。不涉及数组复制。我认为你在理解这一点上与OP有着完全相同的问题。