2017-08-15 67 views
2

我认为Ruby中的所有类都可以实例化。什么阻止Integer类使用new方法实例化?为什么我不能在Ruby中实例化Integer类?

Integer.new 
# => NoMethodError: undefined method `new' for Integer:Class 
+0

“什么能阻止Integer类被'new'方法实例化?” - 有什么不清楚的错误信息? “Integer.new”不起作用的原因是*没有*'Integer.new'。 –

回答

7

有一些这些。除了Integer,FloatSymbol,您也不能创建TrueClassFalseClassNilClass的新实例。

这些类(及其各自的实例)在Ruby中都是特殊的,并且在内部以特定方式处理。

以小整数为例,Ruby隐式处理这些。 Ruby不会为每个整数创建一个新的“实际的”Ruby对象(这将非常浪费),而是将这些对象仅存储为由object_id表示的数值。因此,你在Ruby中观察到的Integer类的实例实际上是单个值im memory(或多或少)。为了能够解决这个问题,Ruby保留所有奇数的object_id作为整数值。因此,数13object_id,数量25object_id等等...

由于Ruby语言本身这个特殊的处理,你不能创建一个新的整数实例。现在考虑到整数本身总是不变的(也就是说,它们不能被改变),它们只是首先由它们的数值定义。 (注意,这只适用于小整数,对于较大的整数,取决于你是在32位还是在64位体系结构上运行,如果整数不能适合这是由Ruby内部处理的,基本上是语言本身的一个实现细节。)

+2

从技术上讲,它们是实际的(不含引号)ruby对象('rb_cInteger')ruby只是不会创建“new “ 那些。 'Numeric'作为父类是一个实际的ruby对象,可以被实例化。 'Float','Integer'等简单地取消定义'#new',以便它们可以是立即数(不可变且始终按值传递)。但对于一个相当复杂的主题,这是一个相当简洁的答案。 – engineersmnky

3

您不能在Ruby中分配Integer的堆对象。在Ruby中,整数是立即数,这意味着你不能拥有对象的实例化版本。由于您无法分配它们,因此无法创建子类并分配子类的实例。

+0

'Numeric'不是直接的,可以实例化(Numeric.new),并根据以下标准进行子分类。继承的类**必须**定义'#coerce'并且应该实现算术运算符的对象特定版本,例如''''''''''''''''''''整数''和'浮点数'子类'数字',但不能被实例化,它们通过简单地不定义“实例化”('#new')分配函数,但这是特定于那些类而不是“数字”作为一个整体。 [源代码参考](https://github.com/ruby/ruby/blob/trunk/numeric.c#L5265) – engineersmnky

相关问题