2012-01-14 36 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