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

con*_*com 3 ruby object

我有这个Ruby代码:

var1 = 10
puts var1.object_id
var1 = var1 + 0
puts var1.object_id
var1 = var1 + 1
puts var1.object_id
Run Code Online (Sandbox Code Playgroud)

输出是:

1> 21
2> 21
3> 23
Run Code Online (Sandbox Code Playgroud)

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

sep*_*p2k 9

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

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


sai*_*ala 5

在Ruby中,Fixnums和true, false,nil以及Symbol■找预定义object_id秒.

1.object_id #=> 3
2.object_id #=> 5
Run Code Online (Sandbox Code Playgroud)

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

但是如果你在Bignums 上运行相同的算法,你会得到不同的object_ids.

a = 1073741824
puts a.object_id # => 7658076
b = a + 0
puts b # => 1073741824
puts b.object_id # => 7287012
Run Code Online (Sandbox Code Playgroud)