作者godfat (godfat 真常)
看板Ruby
标题Re: [问题] 有关於Ruby阵列的问题..
时间Mon Nov 27 18:48:33 2006
1F:推 fuha:感谢指点~v( ̄︶ ̄)y, 我想请问一下 shallow copy 在什麽时候 11/27
2F:→ fuha:会用到啊?(可能是我写得程式不多......╮(﹋﹏﹌)╭..) 11/27
老实讲…我觉得 Array.new size, obj 会这样实作,理由是效率
像是如果你写 Array.new 10, 12, 像 Fixnum 这种 immutable 的东西,
这样做才是正确有效率的。那如果你是真的需要各个不同的 instance 呢?
请自己写…预设使用高效率的做法,大概是这样吧,随便猜的 @_@b
反正也不难写
不过话说回来,其实我讲 shallow copy 和 deep copy 在这里不太正确
因为这两件事都是在指 copy instance 的状况下…(抱歉不知道怎麽修改描述 Orz)
而 Array.new size, obj 的状况并不是真的在 copy instance...
正确的说法是,他使所有的 element 都指向传入的 obj, 没有任何 copy instance 的
动作在。所以以你的例子来看的话,真正的 shallow copy 也不会造成改一个
却动到全部。
在 Ruby 里,shallow copy 用 obj.dup 表示,deep copy 用 obj.clone 表示
也就是说,在我所举的例子里,用 obj.dup 就不会使得改一个却动到全部了
(除非里面还有再一层的 instance...)
用另一个 C++ 术语的话… shallow copy 就是 bitwise copy,
把记忆体整份拷贝过去,所以所有的变数都是指向同一个 instance 的
(因为变数里记录的是物件地址,而非物件本身)
至於使用时机呢,我也随意举一个例子,使用前一个例子的
Array.shallow_new 和 Array.deep_new...
假设你现在有一个 Map, 里面放着一些 Square, 而每个 Square 有变数
记录着他是属於哪一个 Map
class Square
def initialize owener
@owener = owener
end
attr_reader :owener
end
接下来你需要一个 Map, 在初始化的时候把整组的 Square 建立起来
class Map
def initialize
@squares = Array.shallow_new 5, Array.shallow_new(5, Square.new(self))
end
end
这样你就可以产生一个 5*5 的 Square 阵列,里面每个 Square 都是各自独立的
而且全部指向同一个 Map, 而不是全部指向各自独立的 Map........
虽然如果在 Square#clone 中将整个 Map 重新建构出来是个很怪的行为,
但是 deep copy 本身的意思就是这样…如此将产生无数的 Map,
甚至是无穷递回…… XDD
当然了,Square#clone 是有可能真的有必要,例如每个 Square 有个 Date 物件,
表示这个 Square 被产生出来的时间,如此一来 clone 还是有必要特别去处理这个
Date, 但是 Map 同样不该被重新 clone 一份出来
这也是为什麽每个物件的 clone 需要自己定义的原因
==
抱歉讲得很乱 Orz...
好像有点在胡言乱语了 -_-b
--
生死去来、棚头傀儡、一线断时、落落磊磊
《花镜》-世阿弥
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.228.73.152
3F:推 fuha:虽然我已经看的乌煞煞...~但是还是~感谢~ 11/28 10:51
4F:推 godfat:有问题就发问吧… XDb 11/28 15:08