使用Ruby符号

Luc*_*uke 14 ruby symbols

我第一次尝试学习Ruby是在2年前,现在我又开始了.我停止的原因是因为我无法理解Symbol类.而现在我再次处于同一点,完全迷失在何时以及为何使用Symbols.我已经阅读了Stackoverflow上的其他帖子以及Googled的几个解释.但我还不明白.

首先,我认为符号只是一种创建某种"命名常量"的方法,而不必像Java那样经历相同的过程.

:all 
Run Code Online (Sandbox Code Playgroud)

而不是使用任意值创建常量 public static final String ALL = 8;

但是,当你使用它时,它是没有多大意义的,例如attr_accessor :first_name etc. Are Symbols只是一个轻量级的String类吗?我在理解如何解释,何时以及如何在我自己的类和框架中使用符号时遇到问题.

Ser*_*sev 35

简而言之,符号轻量级字符串,但它们也是不可变的,不可垃圾收集.

你应该不是在你的数据处理任务(记住,一旦创建符号,它不能被破坏),用它们作为不可改变的字符串.您通常使用符号来命名.

# 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)  
Run Code Online (Sandbox Code Playgroud)

我们来看第一个例子params[:id].在一个中等大的rails应用程序中,可能有数百/数千个散布在代码库周围的应用程序.如果我们用字符串访问该值params["id"],则表示每次都要进行新的字符串分配(之后需要收集该字符串).在符号的情况下,它到处都是相同的符号.内存分配器,垃圾收集器甚至是你的工作量减少(:输入速度比更快"")

如果你的代码中经常出现一个简单的单字符串,并且你没有做任何时髦的事情(插值,gsub,upcase等),那么它很可能是一个很好的候选者.

但是,这是否仅适用于作为实际程序逻辑的一部分使用的文本,例如命名,而不是在实际运行程序时获得的文本...例如来自用户/ Web等的文本?

我想不出一个案例,我想将数据从用户/ web转换为符号(解析命令行选项除外).主要是因为后果(曾经创造过的符号永远存在).

此外,许多编辑器为符号提供不同的着色,以在代码中突出显示它们.看看这个例子

符号vs字符串


Tod*_*obs 11

O'Reilly Ruby Cookbook(第15页)引用Jim Weirich的话说:

  • 如果对象的内容(字符序列)很重要,请使用字符串.
  • 如果对象的标识很重要,请使用符号.

符号通常用作哈希键,因为它是密钥的标识,这很重要.使用Object#send等特定方法传递消息时也需要符号.


ste*_*lag 8

Ruby实现通常有一个表,用于存储所有类,方法和变量的名称.它指的是表中位置的方法名称,避免了昂贵的字符串比较.但您也可以使用此表并为其添加值:symbols.

如果您编写的代码使用字符串作为标识符而不是文本内容,请考虑使用符号.如果你编写的方法要求参数为"男性"或"女性",请考虑使用:male:female.比较两个符号的相等性比字符串更快(这就是符号构成好的哈希键的原因).


Ric*_*ich 5

符号用于命名语言中的东西:类的名称,方法的名称等.这些非常类似于字符串,除了它们永远不会被垃圾收集,并且对相等性的测试被优化为非常快.

Java实现有一个非常类似的东西,除了它不适用于运行时使用.我的意思是,当你编写java代码时obj.someMethod(4),字符串'someMethod'被编译器转换为嵌入在.class文件中的查找表中的符号.这些符号类似于"特殊"字符串,它们不是垃圾收集的,并且可以非常快速地比较相等性.这几乎与Ruby相同,只是Ruby允许您在运行时创建新符号,而Java只允许在编译时使用它.

这就像创建新方法一样 - Java允许它在编译时; Ruby允许它在运行时.