2012-01-14 60 views
2

帮我看看这部分代码:使用数组操纵由地址

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] :-(

当阵列工作我推测,红宝石使用地址... 为什么这个代码不工作? 我想这样做(在C):

struct ctx 
{ 
uint class_array[10000] 
} 

void func(struct *ctx) 
{ 
uint* local_array = &ctx->class_array 
local_array[0] = 4; 
ctx->class_array[0] => 4 
} 

回答

1

问题是与这部分代码:

local_array = ctx.class_array 
local_array = [4,3,5,5,6] 

这不符合你的想法。第二行创建一个新列表并将其分配给本地变量,从而将引用替换为ctx.class_array。它会不是 touch ctx.class_array。一个等效的C代码将以相同的方式工作,所以我认为你不仅在这里有一个Ruby问题。

在C中,你可以使用指针来解决这个问题。在Ruby中,你可能想要么:

local_array = ctx.class_array 
local_array.replace [4,3,5,5,6] 

或者干脆(好多了!)

ctx.class_array = [4,3,5,5,6] 

顺便说一句,你的C程序的直接翻译也将工作:

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

非常感谢!我只是明白!我会用'替换'而不是!但是,如果我想将另一个数组附加到local_array,我应该写什么代码?我的意思不只是local_array = [某事];如果我编写local_array + = another_array,那么ruby也会创建新的局部变量而不是使用ctx。变量? – user1119425 2012-01-14 21:45:16

+0

@ user1119425因为您告诉它创建一个局部变量,然后将局部变量分配给其他东西。 – 2012-01-14 21:51:02

+0

@ user1119425:'local_array + = another_array'与'local_array = local_array +另一个数组'相同,所以我的解释也适用于此。你可以使用'local_array.push(* another_array)',但这很丑陋,这是件好事。另外,如果这个答案对你有帮助,你将被邀请upvote并接受。 – 2012-01-14 21:54:59

0

你为什么不跳过你的函数的第一线,只是直接分配,像这样:

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

是的,我知道它:-)但我问“为什么这个代码不工作?” ) – user1119425 2012-01-14 21:48:33

+0

它不起作用,因为数组被指定为副本而不是Ruby中的指针。 – 2012-01-14 21:50:10

+1

@Jesse:这显然是错误的。他们*是*通过引用分配和* NOT *复制。 – 2012-01-14 21:56:03

0

它可以通过只完成调整顺序:

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

为什么superflous临时变量和回报? – 2012-01-14 21:36:54

+0

我知道,但我想了解红宝石是如何工作的。 – user1119425 2012-01-14 21:47:40

1

在你的情况下,ctx实例拥有对@class_array实例变量中的数组对象的引用。在func方法中,将创建对该同一对象的新引用,并将其分配给局部变量local_array

当您指定[4,3,5,5,6]local_array,你是不是覆盖由ctx引用,要覆盖在local_array举行的参考,使它引用新的数组对象。

在三分球方面,你在做什么是类似于此:

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段,以红宝石产生全功能代码:

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

ctx.class_array[0] 
=> 4 

它的工作原理,因为local_array指的是同一个对象ctx.class_array