为什么Ruby为“var = var + 1”而不是“var = var + 0”创建一个新对象?

时间:2012-12-27 21:35:53

标签: ruby object

我有这个Ruby代码:

var1 = 10
puts var1.object_id
var1 = var1 + 0
puts var1.object_id
var1 = var1 + 1
puts var1.object_id

输出结果为:

1> 21
2> 21
3> 23

问题:为什么Ruby在添加非零值时会创建新对象,但在添加0时却不会创建新对象?

4 个答案:

答案 0 :(得分:9)

使用Fixnums时,内部Ruby¹根本不会创建对象。相反,实现使用“标记”指针,即如果设置了指针的最低有效位,Ruby理解该指针实际上不指向对象,而是直接编码Fixnum的值。因此,具有相同数值的Fixnum将始终由相同的指针值表示。

¹我的意思是官方的Ruby解释器 - 其他实现可能会以不同的方式处理它。

答案 1 :(得分:5)

在Ruby中,Fixnumtrue, falsenilSymbol已预先定义object_id

1.object_id #=> 3
2.object_id #=> 5

0添加到小整数不会更改其值,因此其object_id保持不变。

但是,如果您在Bignum上运行相同的算术,则会得到不同的object_id

a = 1073741824
puts a.object_id # => 7658076
b = a + 0
puts b # => 1073741824
puts b.object_id # => 7287012

答案 2 :(得分:2)

没有。 1011是Fixnums。正弦每个Integer值只有一个Fixnum实例,10有一个object_id,11有一个object_id。这就是你所看到的。

答案 3 :(得分:2)

Ruby有预定义的对象

irb(main):001:0> 10.object_id
=> 21
irb(main):002:0> 11.object_id
=> 23

这是一些自然数字甚至更多

irb(main):003:0> true.object_id
=> 2
irb(main):004:0> false.object_id
=> 0
irb(main):005:0> nil.object_id
=> 4
irb(main):006:0> 0.object_id
=> 1
irb(main):007:0> -2.object_id
=> -3

并且这些ID不会改变