2017-08-15 97 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

相關問題