Ruby教學 - 符號(Symbol)
1. 語法
符號類似一種無法修改的字串,使用冒號(:)開頭,有以下三種使用方式:
- 冒號加名稱,:symbol
- 冒號加單引號字串,:'symbol'
- 冒號加雙引號字串,:"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. 轉型
符號可以用以下轉型函式:
- to_s: 轉字串
- ...
如下範例:
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"