作者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