Project1

标题: 询问脚本:关于clone和dup [打印本页]

作者: tan12345    时间: 2013-12-18 10:02
标题: 询问脚本:关于clone和dup
最近看了随机属性装备的脚本以及菜鸟飞啊飞的无限宠物生成功能有个想法:
就是是否可以使用扩展数据库的功能来实现同一人物无限加入队伍,然后就有以下疑问
RUBY 代码复制
  1. actor = $data_actors(id)
  2. pid = $data_actors.size
  3. $data_actors.insert(pid,actor)

以上代码可以将id号的actor插入数据库,从而可以做到同一人无限加入的现象,我就好奇,如果语句
RUBY 代码复制
  1. $data_actors.insert(pid,actor)

改成
RUBY 代码复制
  1. $data_actors.insert(pid,actor.dup)


RUBY 代码复制
  1. $data_actors.insert(pid,actor.clone)

有什么区别吗?是否达到的目的都一样?(随机属性装备里使用的是dup,为什么?)
作者: 国产吃货    时间: 2013-12-18 11:25
本帖最后由 国产吃货 于 2013-12-18 11:28 编辑
  1. clone
  2. dup
  3. 生成物件的副本。clone 返回对象的完整副本,包括冻结状态和特殊方法。而 dup 只有复制对象内容而已。
  4. 注意,clone 和 dup 执行的是简单复制。所复制的是对象本身,而不是对象所指的对象(例如数组元素)。
  5. 复制的对象
复制代码
以上来自Object 物件类的定义[所有类的超类,定义了一般对象的行为。]
作者: tan12345    时间: 2013-12-18 11:30
国产吃货 发表于 2013-12-18 11:25
以上来自Object 物件类的定义[所有类的超类,定义了一般对象的行为。]

能结合我的代码具体解释吗?这段解释我看过了的,可是还不是很理解。而且我主要想问
$data_actors.insert(pid,actor)和$data_actors.insert(pid,actor.clone)和$data_actors.insert(pid,actor.dup)的区别
作者: 国产吃货    时间: 2013-12-18 11:36
tan12345 发表于 2013-12-18 11:30
能结合我的代码具体解释吗?这段解释我看过了的,可是还不是很理解。而且我主要想问
$data_actors.insert ...

我的理解是:
$data_actors.insert(pid,actor)
是向$data_actors的pid位后插入actor这个数据
$data_actors.insert(pid,actor.dup)
$data_actors.insert(pid,actor.clone)
是向$data_actors的pid位后插入actor这个数据的翻版
但是我估计,就算你重复多次运行
$data_actors.insert(pid,actor)
也会重复多次的插入。
  1. insert(nth, [val[, val2 ...]])
  2. 在第 nth 个元素前面插入第二个参数以及后面的所有参数。
复制代码
上面是数组类insert方法的解释。
如此看来,插入是可以无限制的插入,不存在数据重复就不能插入的问题。
(本吃货也是菜鸟,如果有不对的地方,各位撸过的大神一定要及时修正啊呜)
作者: tan12345    时间: 2013-12-18 12:08
国产吃货 发表于 2013-12-18 11:36
我的理解是:
$data_actors.insert(pid,actor)
是向$data_actors的pid位后插入actor这个数据

结合RMVA,我可以理解为这3行代码没有区别吗?我这行代码的功能是向数据库actor插入新数据,将id号actor插入到数据库中,对我来讲,只要将对应id号的所有数据(包括名字、职业、初始装备、可用装备等)插入到数据库里就可以了
作者: 无脑之人    时间: 2013-12-18 12:17
应该不会出问题,但是是不必要的,或者说是不该这样做的【降低效率】
按值传递要视情况而定,一般来讲按引用传递就已经可以了
作者: tan12345    时间: 2013-12-18 12:20
无脑之人 发表于 2013-12-18 12:17
应该不会出问题,但是是不必要的,或者说是不该这样做的【降低效率】
按值传递要视情况而定,一般来讲按引 ...

那应该如何改进?可以将代码改一下给我参考吗?谢谢了
作者: 铃仙·优昙华院·因幡    时间: 2013-12-18 12:24
dup 复制只复制 实例 的内容. clone 除了内容, 还可以复制与 实例 有联系的东西, 比如说单例方法.

RUBY 代码复制
  1. str = "66"
  2.  
  3. def str.show
  4.   p "77"
  5. end
  6.  
  7. str_clone = str.clone
  8. str_dup = str.dup
  9.  
  10. str_clone.show #=> "77"
  11. str_dup.show   #=> NoMethodError


不过 dup 和 clone 都是浅复制, 对于一些实例有引用的东西, 就不能很好的复制了.
RUBY 代码复制
  1. str = [66, "66"]
  2.  
  3. str_dup = str.dup
  4. str_dup[1][0] = "7"
  5. str_dup[0] = 77
  6. p str #=> [66, "76"]
  7. p str_dup #=> [77, "76"]
  8.  
  9. str = [66, "66"]
  10. str_clone = str.clone
  11. str_clone[1][0] = "7"
  12. str_clone[0] = 77
  13. p str #=> [66, "76"]
  14. p str_dup #=> [77, "76"]

作者: tan12345    时间: 2013-12-18 12:33
铃仙·优昙华院·因幡 发表于 2013-12-18 12:24
dup 复制只复制 实例 的内容. clone 除了内容, 还可以复制与 实例 有联系的东西, 比如说单例方法.

str = " ...

第一段代码看懂了;
第二段代码疑问:我改的是dup或clone的,为什么原对象(本体)也跟着变了?
作者: 铃仙·优昙华院·因幡    时间: 2013-12-18 12:37
tan12345 发表于 2013-12-18 12:33
第一段代码看懂了;
第二段代码疑问:我改的是dup或clone的,为什么原对象(本体)也跟着变了? ...

因为 dup 和 clone 无法复制类似 字符串啦, 类实例 等变量的引用.

Ruby 里这里东西是用引用地址来保存的, 并不是像数字什么的直接保存内容.

所以 代码二 中, 数组里的那个字符串就是引用了.

说白了, 就是那个字符串并没有复制, 而且直接拿来用的.
作者: tan12345    时间: 2013-12-18 12:56
铃仙·优昙华院·因幡 发表于 2013-12-18 12:37
因为 dup 和 clone 无法复制类似 字符串啦, 类实例 等变量的引用.

Ruby 里这里东西是用引用地址来保存的 ...

OK,了解,谢谢
作者: 铃仙·优昙华院·因幡    时间: 2013-12-18 13:02
如果真的要完全复制一个实例的话, 可以这么写:
  1. Marshal.load(Marshal.dump(object))
复制代码

作者: 喵呜喵5    时间: 2013-12-18 13:46
楼上说的很详细了,我再补充一点,dup和clone都会复制对象的污染状态,同时一个能复制冻结状态,另一个不能
当然,对于一个RM的使用者来说,上面两条没有什么了解的必要




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1