語法

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

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

如下範例:

1
2
3
p :symbol1    # :symbol1
p :"symbol2" # :symbol2
p :'symbol3' # :symbol3

程式解析

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

1
2
3
4
var = "value"

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

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

符號的操作

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

1
2
3
4
5
6
symbol = :"I lose"

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

轉型

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

  1. to_s: 轉字串

如下範例:

1
p :symbol.to_s  # "symbol"

字串 vs 符號

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

1
2
3
4
puts "string".object_id # 2157007700
puts "string".object_id # 2157007540
puts :symbol.object_id # 391528
puts :symbol.object_id # 391528

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

1
2
3
4
symbol = :symbol
puts Symbol.all_symbols.length # 2399
symbol.upcase
puts Symbol.all_symbols.length # 2400

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

1
2
3
4
5
6
str = "symbol"
symbol = :symbol

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

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

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

1
2
3
hash = {:key => "symbol", "key" => "string"}
p hash[:key] # "symbol"
p hash["key"] # "string"

延伸閱讀

上一篇 Ruby 教學 - 字串 (String)
下一篇 Ruby 教學 - 陣列 (Array)