查看: 3037|回复: 10

[讨论] 关于Ruby的一些不用 clone 就会数据崩溃的指令操作

[复制链接]
梦石
24
星屑
8942
在线时间
248 小时
注册时间
2020-12-4
回帖
259

极短24获奖极短23获奖极短22获奖

发表于 2022-12-15 00:20:50 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 纯属小虫 于 2022-12-15 14:07 编辑

Ruby学习得不是很扎实
一直摸不清面向对象的真正意义是什么
有人说,所有的变量其实都只是给对象贴一个标签,“变量名 = 变量名”的意义更像是给对象贴上一个不同名的标签,但本质还是同一个对象

直到今天发现了以下几个问题,才好像发现了雷区......

"="  !=  "copy"

[fold=试错code]
[pre lang="ruby"]# ======================================================================
# ======================================================================
# ======================================================================
# 字符串不要随便用 带 ! 的正则提取指令

a = "我是一个字符串【哈哈】你好啊【耶耶】"
c = a.clone
b = a
data = []
while b.slice!(/【(.*?)】/)
  data << $1
end
p a     #>>> "我是一个字符串你好啊"
p b     #>>> "我是一个字符串你好啊"
p c     #>>> "我是一个字符串【哈哈】你好啊【耶耶】"
p data  #>>> ["哈哈","耶耶"]

# 用之前请一定要将字符串给 clone 了!
# 不然会把本体也给改掉!

# ======================================================================
# ======================================================================
# ======================================================================

# 不过,split 等自带了clone 的效果,所以之前忘记添加clone的字符串处理,由于在
# 处理前使用了split的命令,所以之后出现了 slice! 也并没有出错!

a = "我是一个字符串●【哈哈】你好啊【耶耶】"
c = a.split(/●/)[1]
b = c
data = []
while b.slice!(/【(.*?)】/)
  data << $1
end
p a     #>>> "我是一个字符串●【哈哈】你好啊【耶耶】"
p b     #>>> "你好啊"
p c     #>>> "你好啊"
p data  #>>> ["哈哈","耶耶"]

# ======================================================================
# ======================================================================
# ======================================================================

# 同样 array中的 = 的指令也会出现这样的问题
a = [1,2,3,4]
b = a
c = a.clone
b[3] = nil
p b   #>>> [1,2,3,nil]
p a   #>>> [1,2,3,nil]
p c   #>>> [1,2,3,4]

# 看样子在处理数据的时候,尤其是copy一个数据的时候,得小心![/pre][/fold]

想请求有经验的大佬们讲解一下,哪些情况下,只用 = 得来的数据,在改变其的时候会连母体也一起改掉
什么情况下需要用clone指令
什么情况下用 = 给变量赋值后,要注意哪些操作可能改变“母变量”
hmmmmm,如果有“面向对象”的比较易懂的讲解,也可以请教一下~~~
梦石
0
星屑
8003
在线时间
1184 小时
注册时间
2007-7-29
回帖
2014
发表于 2022-12-15 03:15:17 | 显示全部楼层
片面上你可以理解除了数字(numeric),其他的等于(=)皆为指针赋值,所以用a=b时不然a还是b,都是指向同个对象。
不过文字串重定义了(+)和(-),所以哪怕是用(=)赋值也会返回本体的克隆。举例:
  1. a = "Hi"
  2. b = a
  3. b += " World"
  4. p a # => Hi
  5. p b # => Hi World
复制代码

至于slice!或者sub!等并不会返回本体克隆,所以会直接对原对象操作。
函数的返回必须查了官方文档才会知道。

评分

参与人数 1赞 +1 收起 理由
纯属小虫 + 1 塞糖

查看全部评分

回复

使用道具 举报

梦石
1
星屑
23236
在线时间
9564 小时
注册时间
2012-6-19
回帖
7018

开拓者短篇九导演组冠军

发表于 2022-12-15 12:10:01 | 显示全部楼层
小 心 浅 拷 贝

  1. data = [1,2,3]
  2. data2 = [4, data]

  3. data3 = data2.clone
  4. data3[0] = 5
  5. data3[1][0] = 5

  6. msgbox data
  7. msgbox data2
  8. msgbox data3
复制代码

点评

这样写,是不是 data 会变成 [5,2,3]; data2 还是 [4,data],但是data变了 0.0  发表于 2022-12-15 14:12

评分

参与人数 1赞 +1 收起 理由
纯属小虫 + 1 塞糖

查看全部评分

回复

使用道具 举报

老鹰

梦石
40
星屑
37812
在线时间
7091 小时
注册时间
2012-5-26
回帖
3297

极短24评委极短23参与极短22参与极短21评委老司机慢点开短篇十吟唱者组别冠军开拓者剧作品鉴家

发表于 2022-12-15 12:38:12 | 显示全部楼层
你要这样想,等号是给一个变量对象起名字
这个变量对象是在起名字之前生成的,不是
所以再次调用等号的时候,还是给它起个新名字

而调用clone的时候,就是生成一个新的它

评分

参与人数 1赞 +1 收起 理由
纯属小虫 + 1 塞糖

查看全部评分

回复

使用道具 举报

梦石
0
星屑
42235
在线时间
6017 小时
注册时间
2006-11-10
回帖
6966
发表于 2022-12-15 15:35:03 | 显示全部楼层
本帖最后由 灯笼菜刀王 于 2022-12-15 15:37 编辑

简单的说, 要使用 F1 里有注明 "返回本身" 的命令, 都会改动本体, 如果不想动本体, 那就给它clone

而不让你clone的对象, 会给你弹无方法错误, 那就表示它可以直接 a = b

评分

参与人数 1赞 +1 收起 理由
纯属小虫 + 1 塞糖

查看全部评分

回复

使用道具 举报

梦石
0
星屑
6483
在线时间
119 小时
注册时间
2020-1-8
回帖
205
发表于 2022-12-15 15:46:39 | 显示全部楼层
可以看F1的Object部分
ruby对象 可以简单分为 立即值对象(Object#dup有提到) 与 非立即值对象
Object#object_id F1定义: 返回与各个对象对应的唯一的整数。但是,为某对象分配整数的具体情形并不固定。

个人理解:
“变量 = ??”    可以看作   "变量 = ??.object_id"
代码执行大概过程:变量名 => 变量值 => 对象object_id => 对象 => 调用方法什么的

方法也可以简单分为 破坏性方法 与 非破坏性方法,这个就看文档,一般都会说明,能记住最好,
起码得有点印象,至少能快速搜索到相关内容,再就是多用用,错多了就记住了。

“面对对象”,直接网上搜索吧……,个人目前理解就是少写些代码

评分

参与人数 1赞 +1 收起 理由
纯属小虫 + 1 我很赞同

查看全部评分

回复

使用道具 举报

梦石
0
星屑
4756
在线时间
389 小时
注册时间
2012-11-8
回帖
235
发表于 2022-12-16 09:53:52 | 显示全部楼层
之前数组内的字符串用数组clone没用。。于是后面碰上直接深拷贝完事。。。
  1. class Object
  2.   def deep_clone
  3.     Marshal::load(Marshal.dump(self))
  4.   end
  5. end
复制代码

点评

了解了,感恩~  发表于 2022-12-16 13:41
会增加内存占用,对象比较大的话可能会卡顿  发表于 2022-12-16 13:29
听起来很强大的亚子。那么深拷贝可以无脑用吗,有没有什么副作用~~~  发表于 2022-12-16 12:42
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部