我第一次尝试学习Ruby是2年前,现在我已经重新开始。 我停下来的原因是因为我无法理解的符号类。 现在我在同一地点再次,完全失去了在何时以及为什么您使用的符号。 我已阅读#2以及Google搜索其他职位的几种解释。 但是,我还没有理解它。
首先,我觉得符号只是为了创造某种“命名常量”,而不必经历同样的过程中让我们说Java的一种方式。
:all
而不是使一个常数与任意的值public static final String ALL = 8;
然而,当您在如使用它并没有多大意义attr_accessor :first_name etc.
符号的定义只是一个轻量级的String类? 我有问题,我的理解应该如何解释,何时以及如何使用符号都在我自己的类和框架。
总之,符号是轻量级的字符串,但他们也都是不可变的和非垃圾收集的。
你不应该在你的数据处理任务(记住,一旦创建符号,它不能被破坏),用它们作为不可改变的字符串。 您通常使用的符号来命名的东西。
# typical use cases
# access hash value
user = User.find(params[:id])
# name something
attr_accessor :first_name
# set hash value in opts parameter
db.collection.update(query, update, multi: true, upsert: true)
让我们第一个例子, params[:id]
在一个中等大的Rails应用程序可能有数百/千那些散落各地的代码库。 如果我们访问的值用字符串, params["id"]
每次这意味着新的字符串分配(而该字符串需要被收集之后)。 在符号的情况下,它实际上是到处都是一样的符号。 (内存分配,垃圾收集器,甚至你少工作:
快比键入""
)
如果你有一个经常出现在你的代码一个简单的字串,你不要做一些时髦给它(插值,GSUB,upcase,等等),那么很可能是个不错的人选是一个符号。
然而,这是否仅适用于作为实际的程序逻辑的一部分,如命名,而不是你,而实际运行的程序文本文字...比如从用户/网络等的文本?
我不认为,我会希望把从用户/网络数据符号(除用于解析命令行选项,也许)单宗。 主要是因为后果(一旦创建符号长生不老)。
此外,许多编辑器符号提供不同的颜色,以突出它们的代码。 看看这个例子
O'Reilly的红宝石食谱 (第15页)引用吉姆·韦里奇的话说:
- 如果该对象的内容(字符序列)是重要的,使用一个字符串。
- 如果该对象的身份是很重要的,使用符号。
符号通常作为哈希键,因为它是很重要的关键的身份 。 符号是通过使用某些方法,如对象#发送邮件时也需要。
一个Ruby实现通常具有这样存储的所有类,方法和变量名的表。 它是指通过在表中的位置说的方法名,避免了昂贵的字符串比较。 但是,你可以使用此表也和增加值是: symbols
。
如果你写一个使用字符串作为标识符,而不是其文本内容的代码,考虑符号。 如果你写的期望一个参数是“男”或“女”的方法,可以考虑使用:male
和:female
。 两个符号的相等比较比字符串快(这就是为什么符号好好哈希键)。
符号用于在语言命名的东西:类的名称,方法等的名称。这些都非常喜欢的字符串,除了他们不能被垃圾收集,以及平等的测试进行了优化,非常快。
Java的实现有一个非常类似的事情,但它不适用于运行时使用。 我的意思是,当你写Java代码一样obj.someMethod(4)
字符串“的someMethod”是由编译器转换成嵌入在查找表中的.class文件的符号。 这些符号像“特殊”串哪些不是垃圾收集,这是非常快的,比较平等。 这几乎是相同的红宝石,除了红宝石让你在运行时创建新的符号,而Java只允许它在编译的时候。
这就像创造新的方法 - Java允许它在编译时; 红宝石允许它在运行时。