作者godfat (godfat 真常)
看板Ruby
標題Re: [Ruby] 想請問一下symbol的用法?
時間Mon Dec 18 17:26:33 2006
※ 引述《fuha (mimi)》之銘言:
: 有關於symbol的用法上,小弟一直搞不是很懂?~
: symbol的使用時機、好處???
因為我程式寫得不多,大部份只是無聊拿出來練練
所以這部份可能會說得不太對… @_@
不過我個人覺得 :symbol 是個相當方便的機制
最主要就是拿來當 identifier
簡單地說,我們常常會有需要替一群的東西給定一個方便辨識身份的東西(id)
偶後我們可以用這個 id 去尋找那個人,算是一種快速而有效率的辨識法
因為你不必把整個東西拿來比較,你只要比較 id 就知道了
這裡舉一個簡單的例子,假設你要設定某樣東西的顏色
最單純的做法,就是用整數,像是 Java 有時候會寫成:
class Color{
public static final int red = 0;
public static final int green = 1;
public static final int blue = 2;
}
然後你要丟顏色給對方,可能寫成:
setColor(Color.red)
會比你直接丟 0 給對方,要來得容易閱讀得多
至於 C++, 則會用 enum
namespace color{
enum {red, green, blue};
}
setColor(color::red);
可以省掉不少打字時間
當然,最容易閱讀與使用的方式,是字串,那麼根本無須設定,
只要知道那東西叫什麼名字就好:
setColor("red");
問題就在於,使用字串會遠比使用整數要來得花時間和空間
效能上並不太可取
於是,:symbol 的好處就是結合字串的方便與整數的效率
你同樣無須設定,直接使用:
setColor(:red);
我不是很清楚 Ruby 的 :symbol 是怎麼做的,所以不知道真正的情況是如何
但我想他的便利與成本,應該是介於整數與字串之間吧
另一個值得一提的是,Ruby 可以藉由 symbol hash 來做 named arguments
比方說你要產生一個新視窗:
Window.new 800, 600, 100, 100, 'XD', ...
這樣超級長的引數列有時候會看到,然而乍看之下根本不知道那些是指什麼
或是變成:
window = Window.new
window.setWidth(800);
window.setHeight(600);
window.setX(100);
window.setY(100);
window.setTitle('XD');
...
這樣反而變得過於囉唆了,而且要寫一堆 method 有夠煩
於是,靠著 Hash 與 :symbol 我們可以這樣改寫:
Window.new :x=>100, :width=>800, :title=>'XD', :height=>600, :y=>100
順序我故意打亂,因為順序並不重要,不需要去記順序
Ruby 有一個簡潔的做法,就是當你最後一個引數全部都是 key=>value 的形式
也就是像上面那樣的話,Ruby 會把這些 key=>value 包成一個 hash 傳進去
也就是,上面的呼叫實際上是:
Window.new {:x=>100, ...}
然後,Window 的 c'tor 再去由這個 hash 去取出他所想要的值
C++ 的 boost 也有一個叫 parameter 的 lib, 就是實作上面的技巧
用起來有點彆扭,不像 Ruby 這麼自然,但還算可以用,如果不介意設定麻煩的話
使用上大概長這樣:(從官網上擷取的範例)
core::depth_first_search((
graph = 'G', visitor = 2, root_vertex = 3.5,
index_map = "hello, world", color_map = false));
有一個額外的括號,因為那整串引數本身是一個 map(像是 Ruby 的 hash)
如果省略掉括號的話,就會變成語法不正確了 :)
就我所知,RoR 本身也是大量運用這樣的技巧,使得你不必去記參數順序,
也不必把一個 statement 拉成一大堆,使用起來相當便利
我覺得 Ruby 最厲害的地方就在於,他可以讓你的 client 變得非常簡潔
C++ 也是可以,問題是如果要提供這樣的 feature, lib 實作起來可是非常非常累的
所以說 Ruby 讓 programming 變得更好玩,並不是隨便說說的 :p
--
Hear me exalted spirits. Hear me, be you gods or devils, ye who hold
dominion here:
I am a wizard without a home. I am a wonderer seeking refuge.
Sacrifice
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.228.85.108
1F:推 dotZu:補充:Java 5也有enum了 12/18 17:53
2F:→ godfat:上次測試的感想是不好用,1.6 又出了 O_o 12/18 18:12
3F:推 fuha:我根據網路上的資料,都沒有讓我很清楚瞭解的範例~有誰可以推 12/18 18:37
4F:→ fuha:薦拿裡有比較好的學習symbol的範例嗎?~感謝回應阿 12/18 18:38
5F:推 godfat:有些東西是需要經驗累積的,有了經驗看了才會有感覺 :) 12/18 18:56
6F:推 fuha:感謝那麼詳盡的回答~ 12/18 19:10
7F:推 xamous:推~我剛看到 symbol 也很疑惑 後來發現幾乎只要把它當字串 12/18 23:01
8F:→ xamous:看就好了... 自己實驗一下,很多時候 symbol 跟字串的使用 12/18 23:02
9F:→ xamous:都是可以互換的... 12/18 23:02
10F:推 jtmh:我覺得重點在「唯一性」,也就是 godfat 大所說的 id. 12/19 05:30
11F:→ jtmh:Ruby 保證同一個 :symbol 一定是指向同一個 Symbol 物件, 12/19 05:31
12F:→ jtmh:而 Ruby 中的字串並沒有這個特性。 12/19 05:32
13F:推 SHBK:可以當hash的key, 節省space, 還有內部實作效率比較好~ 12/19 16:33