1. 語法

符號類似一種無法修改的字串,使用冒號(:)開頭,有以下三種使用方式:

  1. 冒號加名稱,:symbol
  2. 冒號加單引號字串,:'symbol'
  3. 冒號加雙引號字串,:"symbol"

如下範例:

p :symbol1    # :symbol1
p :"symbol2"  # :symbol2
p :'symbol3'  # :symbol3

2. 程式解析

當使用字串形式的時候,也具有和字串一樣程式解析的性質,同樣的是雙引號的時候纔有:

var = "value"

p :"#{var}" # :value
p :'#{var}' # :"\#{var}"

不過一般而言,使用symbol通常是固定值,所以這種動態的用法不常使用。

3. 符號的操作

符號是無法修改的,但有也部分類似字串的方法:

symbol = :"I lose"

puts symbol[4]     # s
# symbol[4] = 'v'  # error
# symbol += 'd'    # error
p symbol.upcase    # :"I LOSE"

4. 轉型

符號可以用以下轉型函式:

  1. to_s: 轉字串
  2. ...

如下範例:

p :symbol.to_s  # "symbol"

5. 字串 vs 符號

符號和字串最主要的差異在於記憶體的管理方式,由於 Ruby中的每個字串都是新的物件,所以即使是相同的字串也會佔用不同的記憶體,而符號則是重復利用:

puts "string".object_id # 2157007700
puts "string".object_id # 2157007540
puts :symbol.object_id  # 391528
puts :symbol.object_id  # 391528

一旦符號被定義或產生,就會被存放在Symbol.all_symbols中共用物件:

symbol = :symbol
puts Symbol.all_symbols.length  # 2399
symbol.upcase
puts Symbol.all_symbols.length  # 2400

字串和符號不相等,所以比較時必須先進行轉型:

str = "symbol"
symbol = :symbol

p str == symbol        # false
p str == symbol.to_s   # true
p str.to_sym == symbol # true

要注意的是,字串轉成符號的動作,會在記憶體中永久的增加一個符號物件,直到程式結束。所以如果字串的變化情形是無窮大將可能造成記憶體洩漏(Memory leak),這種情況下使用符號轉字串比較合適。

另外,在Hash中作為key的時候也需要注意:

hash = {:key => "symbol", "key" => "string"}
p hash[:key]  # "symbol"
p hash["key"] # "string" 
相關文章