Ruby、不可变整数和未使用的对象

Ruby、不可变整数和未使用的对象,ruby,integer,immutability,Ruby,Integer,Immutability,原始对象1现在未使用,这不是很有效。为什么整数在ruby中是不可变的?我看过stackoverflow,但找不到任何解释。想想整数变异的能力,以及ruby程序员需要做什么。这会给他们太多的权力来改变语言观察世界的方式。整数对象是内存中的二进制数序列,如果将该对象增加1,它仍然是1吗?不,这就是为什么Ruby使用变量来指向对象,而不是对其进行变异 从长远来看,不可变整数可以节省消耗。我想你在这里质疑的是ruby的决定,使原始对象不可变,并将其存储在内存中,而不是对其进行变异,这会增加内存消耗?嗯,

原始对象
1
现在未使用,这不是很有效。为什么整数在ruby中是不可变的?我看过stackoverflow,但找不到任何解释。

想想整数变异的能力,以及ruby程序员需要做什么。这会给他们太多的权力来改变语言观察世界的方式。整数对象是内存中的二进制数序列,如果将该对象增加1,它仍然是1吗?不,这就是为什么Ruby使用变量来指向对象,而不是对其进行变异

从长远来看,不可变整数可以节省消耗。我想你在这里质疑的是ruby的决定,使原始对象不可变,并将其存储在内存中,而不是对其进行变异,这会增加内存消耗?嗯,
a
不是一个全局变量,最终应该通过垃圾收集来清除。Ruby使用DRY原则进行对象分配,保留对象而不是反复创建对象是有意义的。如果你有比ruby更多的对象,它必须分配更多的内存,这在操作系统上是很昂贵的,但是你的代码应该知道这一点。当分配的内存太多时,Ruby会释放内存。Ruby对象存储在
Ruby对象堆中,而不是垃圾收集器经常清理的
malloc堆中

如果整数是可变的,那么修改应用程序中其他地方使用的变量将导致难以修复的回归,并会在web应用程序中导致许多问题。关于保留和性能方面的问题,请看以下示例:

a = 1
a += 1
=> 2
观察“保留”了多少对象以及进程消耗了多少内存。现在,想想在一个真实的程序中要保留多少对象,想想内存消耗是否会成为一个真正的问题。如果您发现自己遇到了这个问题(我认为您不会遇到),请将其视为改进代码的通知。

整数和所有整数都是不可变的,因此每个整数只有一个。我们可以通过检查他们的

此行为也以数字形式记录

其他核心数值类(数值类除外)如Integer被实现为立即数,这意味着每个整数都是一个始终按值传递的不可变对象。例如,整数1只能有一个实例。Ruby通过防止实例化来确保这一点。如果尝试复制,则返回相同的实例

在正常使用中,每个整数有一个不可变对象可以节省内存,您将大量使用
1
。共享同一
1
的每个人都可以节省大量内存,但这意味着它必须是不可变的,否则添加到一个对象会改变其他对象,并且会改变其他对象

不必一次又一次地取消分配和分配同一个整数,速度更快,并减少内存碎片。如果它们真的没用过。Ruby的垃圾收集功能正在不断改进,可以使用许多环境变量进行调整

它还简化了它们的实现,提高了它们的性能。不可变对象可以缓存任何计算,因为缓存永远不需要失效

为什么整数在ruby中是不可变的?我看过stackoverflow,但找不到任何解释

让我们假设
Integer
s是可变的:

14

我猜,你找不到任何解释的原因是,大多数人都认为,将
1
的值更改为
1
以外的任何值都会导致一场疯狂的维护噩梦,这是不言而喻的。实际上,在所有现实世界的Ruby实现中,
1
甚至不是一个对象,因此,垃圾永远不会被收集,因为它从一开始就不存在。它的可观察的“对象性”是由Ruby实现合成的(读作“伪造”),但它从来没有作为一个实际的对象存在过。我很好奇这是否有任何用例,以及它的优点?但是为了回答你的问题(这只是一个猜测),我假设制造Ruby的学者们永远无法理解程序员希望1的整数代表除1之外的任何其他数字。尽管如此,我还是很好奇这种情况下哪里会有有效的用例。
require 'newrelic_rpm'

a = 0
loop do
  a += 1
  if a % 10_000 = 0
    p a
    p  NewRelic::Agent::Samplers::MemorySampler.new.sampler.get_sample
  end
end
2.6.4 :001 > a = 1
 => 1 
2.6.4 :002 > a.object_id
 => 3 
2.6.4 :003 > 1.object_id
 => 3 
2.6.4 :004 > b = 1
 => 1 
2.6.4 :005 > b.object_id
 => 3