2007年6月28日 星期四

Ruby的Symbol是什麼?

Ruby Symbol是代表一個字串的符號, 並且有下面兩個特性
1. 不可變動性 (所代表的字串內容不可更改)
2. 唯一性 (系統中代表同一個字串的symbol 是同一個instance)

在Ruby中, Symbol也是一個class, 但是它並不是String的subclass.
Symbol class不提供 Symbol.new 讓我們使用,

如果要產生Symbol的instance要使這個方式
>x = :abc
=>:abc
上面程式告訴Ruby, 我要產生一個Symbol的instance, 他所代表的字串是"abc"
>x.class
=>Symbol
我們可以看出來, x的class是Symbol而不是String
>y = :abc
=>:abc
>x.object_id
=>243938
>y.object_id
=>243938
上面我們看出 Symbol的唯一性, x和y是同一個object. (因為x和y的object_id是一樣的)

Symbol有什麼用? 也就是說Ruby為什麼要有Symbol?
有兩個原因第一是節省記憶體空間(space), 第二是增加執行時的效率(performance)
如果你是Java的programmer,應該知道, Java的String內容是不能改變的. 然後Ruby的String卻完全不是這麼一回事,
>m = "abc"
=>"abc"
>n = "abc"
=>"abc"
>m.object_id
=>23225030
>n.object_id
=>23222010
>m[0]="A"
=>"A"
>m
=>"Abc"
看出來了嗎? m和n都是字串"abc", 但是的卻是不同的instance (object_id不一樣), 而且字串的內容是可以修改的.
但是..........字串是程式中常常用到的, Ruby中的 每一個"abc", 其實都是 String.new("abc"), 如果我們程式中有太多的"abc", 那麼, Ruby就會create一堆的 String instance...., 所以如果我們可以在程式裡多用:abc 來取代"abc", 那麼就可以節省掉一些記憶體的空間. symbol最普遍應用的就是就屬hashmap的key值了.

Symbol第二個好處就是增加執行時的performance, Symbol在ruby內部除了代表一個字串外, 其實也代表了一個數字

如果ruby執行到 m.do_something, 在Ruby的內部, 會在m中找一個名稱叫做 do_something, 如果Ruby用字串比對的方式在m中去找名稱叫 "do_something"的method, 那麼performance將會很低(因為字串的比對是很花時間的), 所以Ruby會將 "do_something"轉成 :do_something, 由於:do_something也代表了某個數字(假設代表的數字是34), 因為Ruby只要在m中尋找 34這一個method, 這樣比用字串比對去找"do_something"要快得多了....
所以在Ruby當中 m.do_something 事實上是呼叫 m.send(:do_something)

沒有留言: