Ruby 一段代码测测你的引用类型功力

anleb · 2012年07月28日 · 最后由 Anleb 回复于 2012年07月28日 · 3700 次阅读
class Fixnum
        attr_accessor :value
end

x=1
x.value=“anleb”

p x.object_id
p x.value.object_id

def change (x)
       p x.object_id
       p x.value.object_id
       #x=2
        x.value=“ruby”
        p x.object_id
        p x.value.object_id
end
change x
p x
p x.value
p x.object_id     
p x.value.object_id

注释部分,注释和不注释结果截然不同。大家一起来讨论下。 结果: 不注释得时候,不会改变 注释的时候, 3 22950410

3 22950410

3 22950330

1 ruby

3 22950330

如果'attr_accessor :value'换成

def value=(value)
@value=value
end
def value
@value
end  

这样大家也可以试试

你应该是少打了一个 change(x) 方法的调用吧。

很佩服楼主,可以写出这么奇葩的代码,不过,要注意代码缩进呀。代码是使用三个波浪号下面的那个反引号.括起来 你改一下吧,刚刚读代码费了好大劲儿。

一个数字的 object_id 任何情况下都是固定的。1 是什么是死的,2 是什么也是死的,双飞燕里翻译做立即值. 所以只要数字不变,object_id 一直就是一样的。当你变为 2, 就变成 2 的立即值了。

至于那个 x=2, 是因为本来 x 是你通过方法的形参传入的那个 x, 不过在方法内部后半部分,你声明了一个本地变量 x, 实际更改的是方法内的本地变量,退出方法之后,实际上显式的还是外边这个 x.

建议 LZ 关注下方法的传参

#2 楼 @zw963 我手机打的,公司不准外网,你没理解我的意思,你 x=2 注释于否答案是不同的

#3 楼 @jjym 答案我知道,你分析下,就会发现里面名堂很大

#2 楼 @zw963 你关注的应该是 value 为什么变

#5 楼 @Anleb 眼拙,看不出来哪里名堂很大 方法传参是传引用的副本

#4 楼 @Anleb

那当然不同了呀。如果没有注释 x = 2, 那么就是在方法内新建了一个本地变量 x, 如果你注释了,方法内的那个 x 就是通过形参传递进来的针对 x 的引用。我大概理解明白你说的名堂了,那就是 integer 因为不是像绝大多数对象那样是值传递,而是引用传递。这就是因为 integer 是立即值的缘故吧。

#7 楼 @jjym

你再看看是副本吗?副本怎么会改变方法外 x 的输出结果呢?

看了 Ruby 重构之后,我发现,是我错了...

#9 楼 @zw963 你发现了,我倒是我有思路,你看看 attr_accessor 返回的是@value可能这个就是原因

楼主真是个标题党! ruby 中,有引用,但是没有引用传递,方法的参数都是值传递的

#11 楼 @googya 能否举个例子

楼主有问题就直接问,觉得结果有啥特别的也最好直接说出来,像这样让人以为有怪异的地方,专门试了一下,发现没啥特别,你这不是浪费大家时间么。

#13 楼 @fsword 10 楼给答案了

需要 登录 后方可回复, 如果你还没有账号请 注册新账号