解决方法
注意,以下所有的都是默认的Ruby,它内部使用YARV,又名“另一个Ruby VM”,像JRuby这样的其他rubies可能会使用不同的内部表示…
好问题.
Ruby使用整数的标记指针,其他所有内容都作为对象的引用进行存储.
他们如何工作?指针中的一位用作标签,如果该位被置位,则指针的其余部分被解释为整数,否则将被解释为地址.
这是因为一个指针中的某些位未被使用.通常不使用内存地址的最低位.大多数系统只允许对齐的存储器地址的地址,例如对齐到4个字节,因此2位可用作标签.然后如果该标签被设置,则指针的另一个31位被解释为整数.
当您查看整数的object_id时,您可以看到这一点
20.to_s(2) # => "10100" 20.object_id.to_s(2) # => "101001"
在某些系统上,使用两个标记位,然后使用其他标记位表示浮点数.还有一些特殊的对象,如nil,true,false,表示为不太可能是有效内存地址的保留号.符号也在内部表示为带标号的整数,但与实际整数不同的位掩码.
所有其他值都表示为指针.
有趣的是,您可以使用ObjectSpace类检查所有这些.
(0..100).each { |n| p([n,ObjectSpace._id2ref(n)]) rescue nil }
在我的系统上打印
[0,false] [1,0] [2,2.0] [3,1] [5,2] [6,-2.0] [7,3] [8,nil] [9,4] [10,2.0000000000000004] [11,5] [13,6] [14,-2.0000000000000004] [15,7] [17,8] [18,2.000000000000001] [19,9] [20,true] [21,10] [22,-2.000000000000001] [23,11] ...