iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
0
自我挑戰組

滿滿的紅寶石不拿嗎?-- 去吧!我把世界上的一切都放在那裡了! 系列 第 16

符號 <> 看!又是一塊歷史正文!讀懂這些,通往 ONEPIECE 的路就不遠了!- 滿滿的紅寶石不拿嗎?

[Day16] 但是歷史正文上的符號真是複雜難懂啊...

哈囉各位晚安,今天要介紹的是符號(Symbol)

大家對符號應該不陌生,畢竟每天傳訊息都會用到啊!
????????????????????? 啊不是這是表情符號...


符號是什麼?

在 Ruby 裡,符號是一種「帶有名字的物件」。
會用冒號 : 開頭來表示符號,同時符號也具有唯一性(immutable),一旦被建立後就無法改變。

最容易看到符號的地方就是在雜湊(Hash)了!我們經常使用符號來表示雜湊裡的鍵(key):

hash = {
  :cat => 1,
  :dog => 2,
  :man => 3
}

也可以寫成這樣:

hash = {
  cat: 1,
  dog: 2,
  man: 3
}

另外,符號也可以拿來指稱方法:

def call_me
  puts "打電話給我!"
end
=> :call_me

符號跟變數有什麼不同?

首先,雖然看起來和變數超級像,但符號它不是「變數」而是「值」。

如果我們把符號當作變數一樣在用:

# 把字串指定給符號
:name = 1

=> SyntaxError ((irb):15: syntax error, unexpected '=', expecting end-of-input)
:name = 1

# 把字串指定給符號
:name = "Hi"

=> SyntaxError ((irb):16: syntax error, unexpected '=', expecting `end')
:name = "Hi"

Ruby 會告訴你這樣的語法是錯誤的!因為按照正常的程式邏輯,我們不能把一個值指定給另一個值。


一個特定符號只有一個 Object_id

任何一個符號都有著自己的記憶體位置,並始終指向那個位置,因此會較省記憶體。比起字串,用符號來當作雜湊的鍵(key),存取效能的表現會更好。

為什麼存取效能更好?原因是當程式在比較兩個物件時,若是符號,程式會直接比對 object_id 是否相同。然而在比對字串時,則是會從第一個字元開始,逐一比對是否相同。因此,在效能上字串的時間複雜度會隨著字元數量增加而提升,但符號就沒有這樣的問題。

接著我們來看看字串和符號的差別:

"hi".object_id
 => 180 
"hi".object_id
 => 200 
"hi".object_id
 => 220 
"hi".object_id
 => 240

:call_me.object_id
 => 2034908 
:call_me.object_id
 => 2034908 

然而,符號用太多而沒有歸還記憶體時,會出現 記憶體流失(Memory leak) 的問題(簡單來說,是一種在設計上造成的記憶體浪費)


其他像是數字或 truefalsenil 的 object_id 也會變動嗎?

數字的 object_id 是固定的,被放在記憶體的奇數位置上。譬如數字 n ,位置就是 2n+1:

1.object_id
 => 3 
2.object_id
 => 5 
3.object_id
 => 7 
5.object_id
 => 11 
8.object_id
 => 17 

truefalsenil 則是在記憶體的偶數位置,也是固定的:

true.object_id
 => 20 
false.object_id
 => 0 
nil.object_id
 => 8

關於 Ruby 的符號今天就介紹到這邊啦!希望之有時間的話能再提一些自己在實際運用上的案例及理解,謝謝大家的觀看!


上一篇
存取限制 <> 原來是海樓石!惡魔果實能力者的剋星 - 滿滿的紅寶石不拿嗎?
下一篇
Block <> 只是想被人需要,我很樂意為你執行! - 滿滿的紅寶石不拿嗎?
系列文
滿滿的紅寶石不拿嗎?-- 去吧!我把世界上的一切都放在那裡了! 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言