2011-01-09 31 views
5

Như đã đề cập trong this answer, Array.new(size, object) tạo một mảng với các tham chiếu size đến cùng một số object.Trong Ruby, tại sao Array.new (kích thước, đối tượng) tạo một mảng bao gồm nhiều tham chiếu đến cùng một đối tượng?

hash = Hash.new 
a = Array.new(2, hash) 
a[0]['cat'] = 'feline' 
a # => [{"cat"=>"feline"},{"cat"=>"feline"}] 
a[1]['cat'] = 'Felix' 
a # => [{"cat"=>"Felix"},{"cat"=>"Felix"}] 

Tại sao của Ruby làm điều này, chứ không phải làm một dup hoặc clone của object?

Trả lời

9

Vì đó là những gì the documentation cho biết. Lưu ý rằng Hash.new chỉ được gọi một lần, vì vậy tất nhiên chỉ có một số Hash

Nếu bạn muốn tạo đối tượng mới cho mọi phần tử trong mảng, hãy chuyển khối tới phương thức Array.new và khối đó sẽ được gọi cho mỗi yếu tố mới:

>> a = Array.new(2) { Hash.new } 
=> [{}, {}] 
>> a[0]['cat'] = 'feline' 
=> "feline" 
>> a 
=> [{"cat"=>"feline"}, {}] 
>> a[1]['cat'] = 'Felix' 
=> "Felix" 
>> a 
=> [{"cat"=>"feline"}, {"cat"=>"Felix"}] 
+2

"Bởi vì đó là những gì tài liệu cho biết." - Tôi đã hy vọng để bật lý do tại sao ngăn xếp một chút xa hơn thế. –

+1

Popping lý do ngăn xếp: bởi vì khi bạn vượt qua trong một đối tượng được sử dụng để điền trước mảng, mảng sẽ được điền trước với đối tượng đó. – yfeldblum

+0

@Justice: Bạn có nghiêm túc hay mỉa mai với nhận xét đó không? –

2

Đối với các lớp học nhất định mà không thể được sửa đổi tại chỗ (như Fixnum s) dưới hình thức Array.new(X, object) hoạt động như mong đợi và có lẽ là hiệu quả hơn (nó chỉ gọi memfill thay vì rb_ary_storeyield ing vào khối):

Đối với các đối tượng phức tạp hơn, bạn luôn có dạng khối (ví dụ: Array.new(5) { Hash.new }).

* Chỉnh sửa: * Đã sửa đổi theo nhận xét. Xin lỗi cho ví dụ ngu ngốc, tôi đã mệt mỏi khi tôi viết điều đó.

+1

Bạn đang thay thế c [1] với một đối tượng mới, thay vì sửa đổi nó. –

+0

>> c [1] << "h"; C#=> ["ah", "ah", "ah", "ah", "ah"] – Nemo157

+0

Xin lỗi, tôi đã viết câu trả lời đó ngay trước khi đi ngủ, bạn đúng. Phần còn lại vẫn phải là sự thật. –

Các vấn đề liên quan