Ruby 关于 ruby 中 object_id 的几个问题

mobiwolf · 2012年03月08日 · 最后由 skandhas 回复于 2012年03月08日 · 4184 次阅读
  1. 为什么系统的 false,true,nil 的对象 id 是固定的呢? 在我的 mac 上分别:0,2,4
  2. 为什么 0,1,2,3.........的数据的对象 id 也是固定的呢? 在我的 mac 上分别为:1,3,5,7.........
  3. 为什么 26 个字母不能类似数字一样的有固定的对象 id 呢?
  4. 对象 id 相同能否证明就一定是同一个对象呢?

1,2: 主要是为了性能。因为在 ruby 中,整数也是对象,但整数使用多,性能这关不好过。所以就特殊处理,如果是 32 位系统,高位为符号位,后 30-1 位为实际数值,0 位为标志,设为 1,这样保证了其 VALUE 为奇数,不会与 malloc 出来的指针重合。这样 30 位内的整数就速度很快了。 转换关系是这样 数字,object_id >> 1 比如 3 就是 1,5 就是 2

false,true,nil 这些因为奇数被占了,就只好用偶数了,malloc 也不会出现这些值,所以也不会与 VALUE 重合。

3:能占的都被占了,字母也分不到了,再说这个属于 String 范围了。

4:object id 一样就是同一对象。

#1 楼 @hhuai +1 补充一点:整数的 id 固定是指 Fixnum,Bignum 的对象 id 不是固定的。 如:

1000000000000000000000000.object_id

我猜一下 你说的 26 个字母不固定是 'a','a'这样 它们是两个字符串,每个都不一样啊 你给个变量赋值试验一下就看到一样了;

>> false.object_id
=> 0
>> true.object_id
=> 2
>> nil.object_id
=> 4
>> 0.object_id
=> 1
>> 1.object_id
=> 3
>> 2.object_id
=> 5
>> 'a'.object_id
=> 2227039220
>> 'a'.object_id
=> 2227035480
>> a = 'a'
=> "a"
>> a.object_id
=> 2227031340
>> a.object_id
=> 2227031340
>> a.object_id
=> 2227031340


#2 楼 @skandhas 对的,这个要看是多少位的系统,32 就可以表示 30 位以内的,64 位就可以表示 62 位以内的。所以 Fixnum 和 bignum 应该是在这里分界,我也没验证,呵呵。

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