鐵 人
Ruby女孩(13):到底字串跟符號什麼時候使用比較好?
2014.Oct.13

還記得前天,我們在說雜湊(Hash)的時候,有提到雜湊的鍵(key)可以用字串(string)或符號(symbol)來表示,例如:

hash1 = { "name" => "Annie", "age" => 25 }  
hash2 = { :name => "Ruby", :age => 21 }  

那篇文章一直強調"string":symbol是不一樣的,那到底哪裡不一樣呢?其實有位厲害的鐵人賽選手在那篇文章下的留言回答了!講得非常清楚噢!快去看快去看,然後我今天的文章就打完了(大誤)XD

從文章留言以及Ruby 中文官方網站中,我們可以得到以下結論:

「到底什麼時候使用symbol、什麼時候使用string呢?」

由於相同名字的symbol 在記憶體裡都占同一個位置,也就是指向同一個物件,所以適用於識別物件,就像是身分證字號一樣,是獨一無二的,永遠不會改變。而每一個string(就算名字一樣),在記憶體中都是不同位置,適用於可改變的內容,例如綽號、電話…等,就不適合拿來作為識別用途。

總而言之(丸尾上身):

如果是物件的識別(例如hash中的key),用symbol。

如果是物件的內容(例如hash中的value),用string。

好的,我們還是來看一看書中對於符號的說明(p.74):

『Ruby 解譯器的典型石作品會維護一份符號表(symbol table),把解譯器已經知道的類別、方法和變數之名稱全都存放在此表中。』

路過的阿嬤問:『阿這嘸蝦咪好康呢?』

『這讓解譯器得以避免大部份的字串比較工作,例如:解譯器在指稱方法名稱時可透過其在符號表中的位置。這將代價較高的字串運算轉換成了代價較低的整數運算。』

路過的阿嬤問:『工蝦啦?』

我想這段的意思,就是指symbol的效能會比string好,因為symbol表中所有東西都有固定的位置,找得比較快,而字串還得去找他在哪,效能就會比較低了。

另外符號的寫法也不是只有:symbol而已噢!看看以下:

:symbol  
:"symbol"  
:'symbol'  

第二和第三行並不是新的寫法,這三行到irb中執行都會得到相同的結果:

=> :symbol  

只是有加上引號只是方便於俱有空格的符號:

:"Hello Kitty"  
=> :"Hello Kitty"  
  
:Hello Kitty  
SyntaxError #要有空格就一定要加上引號才行,不然會噴錯!  

如同字串有%q%Q、陣列有%w%W,symbol也有一個%s(沒有%S)的語法,例如:

%s[Hello]  
=> :Hello  
  
%s[Hello Kitty]  
=> :"Hello Kitty"  

接下來書中提到symbol常被用在一個很特別的情境下,例如:如果我們要查某個物件是不是有支援.each這個方法?我們可以這麼做:

[].respond_to? :each  
=> true # 陣列有.each這方法  
  
{}.respond_to? :each  
=> true # 雜湊也有.each這方法  
  
"".respond_to? :each  
=> false # 字串就沒有.each這方法  
  
"".respond_to? :succ  
=> true # 不過字串有昨天提到的.succ這方法  

總之是個很好的檢測方式,書中就給了個例子:

name = :size  
if xxx.respond_to? name  
  xxx.send(name)  
end  

上面這例子是會測試某物(xxx)是否會回應所指定的方法(.size),如果答案是true,就調用該方法!書中指出這種能夠觀察並修改行為的程式碼稱作「反射程式碼(reflective code)」。

最後最後,我們來看字串與符號的轉換: (還記得以前學過.to_s.to_i.to_a)

符號改成字串一樣可以使用.to_s

:Ruby.to_s  
=> "Ruby"  

也可以用.id2name達到同樣的效果

:Ruby.id2name  
=> "Ruby"  

而字串改符號的話,要使用.to_sym.intern

"Ruby".to_sym  
=> :Ruby  
  
"Ruby".intern  
=> :Ruby  

路過的阿嬤:『安捏喔!賀啦~哇瞭蓋啊~』


第13天~對不起其實根本沒有路過的阿嬤XD

Always remember that the future comes one day at a time. - Dean Acheson

未來,是一天一天的來!

Ruby女孩(14):在Ruby中,萬事萬物都是物件 => true
2014.Oct.14
Ruby女孩(12):Range讓我知道..我是草莓族,Ruby不是QQ
2014.Oct.12
comments powered by Disqus
Designed with by Otis Chou