iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 7
0
Software Development

Ruby 研究 30 天系列 第 7

Day 6 - Symbol in Ruby

Symbol

就外型而言,Symbol 就像在一組變數前面加上冒號。
就分類而言,symbol 就是 Symbol 這個 class 的 instance。

既然是一個物件,就具備以下特性:

  • 本身即帶有值,無法也不須變數指定
  • 擁有自己類別才有的方法

廣泛出沒在 hash 中擔任 key 的腳色

hero = { :name => '埼玉', :年紀 => 25 }

hero.keys         # 印出 [:name, :年紀]

這是我們昨天尾聲的題目:猜猜這行程式碼有幾個參數?

link_to "⾸頁", root_path, class:"btn btn-default", method: "post", confirm: true

答案是 3個 。我們來還原一下就會更清楚:

link_to "⾸頁", root_path, { :class => "btn btn-default", :method => "post", :confirm => true }

宣告一個變數、方法或類別時,會隨之生成一個同名的 Symbol

我們用 all_symbols.count 這個方法來驗證看看:

Symbol.all_symbols.count  # 印出 4688(每台電腦每個版本可能有差異)

pet = 'doggie'           
Symbol.all_symbols.count  # 印出 4689

def pet
  'kitty'
end
Symbol.all_symbols.count  # 印出 4689

pet     # 印出 "doggie"
pet()   # 印出 "kitty"

以上程式碼可以看出,的確在宣告變數之後 Symbol 就偷偷增加了一個,然而相同的名稱只會產出相同的 Symbol 。你可能會想說這樣 Ruby 為什麼不會搞錯?如果說在 Ruby 裡常常都能省略小括號,現在的情境就是少數省略小括號結果不同的時機,在變數跟方法名稱相同的時候,正確的呼叫才能獲得預期的結果。


Symbol vs. String (字串)

Symbol 最常拿來跟 String 比較的原因,也許是兩者在某些狀況能得到相同的結果,又或是說只有 String 擁有to_sym 的方法

擁有相同的方法?

"我是不是很可愛"[1]            # 印出 "是"
:我是不是很可愛[1]             # 印出 "是"
"我是不是很可愛"[1] = "是真的"  # 印出 "是真的"
:我是不是很可愛[1] "是真的"     # 印出 undefined method `[]=' for :我是不是很可愛:Symbol

簡單說就是 String 有的方法 Symbol 不一定具備,查詢 Ruby API 會發現 Symbol 的方法遠比 String 少得多,為什麼不使用 String 就好?
這就好像A的優點比B多10倍,但B有1個優點是A所沒有的,比方說效能上的差異:

3.times do
  puts "hello".object_id
end

# 印出以下結果
# 46947784927160
# 46947784925440
# 46947784908240

3.times do
  puts :hello.object_id
end

# 印出以下結果
# 1928668
# 1928668
# 1928668

相同的物件會有相同的 object_id,但同樣的 "hello" 卻會得到不同的 object_id,這表示它們在記憶體裡是不同的物件,當第二次要取用同一個 Symbol 的時候,它會直接從記憶體裡拿,而不用重新產生一份,因此 Symbol 相對節省記憶體一些。

參考資料:
為你自己學 Ruby on Rails

此文同步刊登於CJ-Han的網站


上一篇
Day 5 - Hash
下一篇
Day 7 - 流程控制與條件判斷
系列文
Ruby 研究 30 天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言