2014-07-24 41 views
9

我想了解一個符號和一個變量在紅寶石之間有什麼區別。他們似乎在給出一個引用對象的名字時做了完全相同的事情。Ruby中的符號和變量有什​​麼區別?

我已閱讀,符號alow更快的程序,但我不知道爲什麼還是他們是如何從以任何方式不同的變量。

+0

另請參見「[什麼是紅寶石冒號運算?(http://stackoverflow.com/questions/6337897/what-is-the-colon-operator-in-ruby)」。 –

回答

11

符號是一種「內在」的字符串,它更像是比任何一個常數。典型的例子:

account_details = { 
    :name => 'Bob', 
    :age => 20 
} 

這裏符號:name:age是一個散列密鑰。他們不要與變數混淆。 account_details是一個變量。

在紅寶石變量是一個手柄,某種類型的對象,並且該對象可以是一個符號。

通常使用字符串時,會導致大量的重複你使用的符號。請記住,字符串通常是不同的對象,其中獨特的符號始終指向同一對象,因此如果頻繁使用它們會更有效。

比較:

"string".object_id == "string".object_id 
# => false 

:string.object_id == :string.object_id 
# => true 

即使這兩個字符串是相同的,他們是獨立的字符串對象。當用作散列值,方法參數以及其他常見情況時,這些對象會很快使您的內存大量複製,除非您使用相同的字符串實例。符號會自動爲您執行此操作。

+0

感謝您的回覆,我認爲我的混淆來自使用符號與屬性。當爲一個實例變量寫一個屬性閱讀器時,在屬性中使用一個符號,但是返回一個變量。在這種情況下,符號如何與實例變量相關聯? – Cu1ture

+2

'attr_accessor:example'的意思是「定義名爲'example'的讀/寫屬性,並定義'example'和example ='方法以及實例變量'@ example'。參數作爲符號傳入,因此接收方法可以告訴它是什麼。請記住,變量名稱是本地的,變量的名稱永遠不會傳入。attr_reader示例意味着「使用任何變量* example *希望它被調用的方式創建一個讀取器」。 'attr_reader'函數無法知道你的變量的名字。這裏的關係是用來傳達想要的名字的符號。 – tadman

4

他們非常不同。變量爲對象提供標籤。符號更像是字符串,除了它們是不可變的並且被存儲在內存中的,所以對同一符號的多個引用不會使用額外的內存。 (用繩子,其中的字符相同的字符串的多個引用將導致該字符串的多個副本對比這一點。)

+0

通過變量引用字符串不會做同樣的事情,並保持內存中的一個實例嗎?與在JS中使用變量以防止重複並且只獲取一次相同的數據相同。 – Cameron

+0

@Cameron:那麼,在類似'a =「字符串」,b = a'的情況下,是的。在「a =」字符串「的情況下; b =「string」,將創建兩個內容爲「string」的對象。 (我不知道JS是如何處理這個的。) – mipadi

5

變量保持到一個對象的引用。例如,變量可以引用字符串和符號,例如:

a = 'foo' 
b = :bar 

在Ruby中的字符串是可變的,這意味着你可以改變他們:'foo' + 'bar'會給一個連接字符串。您可以將符號視爲不可變的字符串,這意味着您無法更改符號::foo + :bar會給您一個錯誤。最重要的是,相同的符號可以引用同一對象:

a = :foo 
b = :foo 
a.object_id # => 538728 
b.object_id # => 538728 

這提高了散列查找和其他操作的性能。

+1

我想指出,未來的讀者能夠添加兩個對象來獲取另一個對象並不意味着該對象是可變的。 Python和Lua中的字符串是不可變的;添加其中兩個給你另一個對象。在Ruby中,字符串是可變的,但添加其中的兩個並不會更改任何基本字符串,它會給您一個新的字符串對象。 – Taywee

相關問題