使用Ruby符号

时间:2012-07-12 08:07:54

标签: ruby symbols

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

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

:all 

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

创建常量

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

5 个答案:

答案 0 :(得分: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)  

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

如果你的代码中经常出现一个简单的单字符串,并且你没有做任何时髦的事情(插值,gsub,upcase等),那么它很可能成为一个符号。< / p>

  

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

我想不出一个我想要将数据从用户/ web转换为符号的情况(除了解析命令行选项之外)。主要是因为后果(一旦创造了符号永远存在)。

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

symbol vs string

答案 1 :(得分:11)

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

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

符号通常用作散列键,因为它是重要键的标识。使用某些方法传递消息时也需要符号,例如 Object#send

答案 2 :(得分:8)

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

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

答案 3 :(得分:5)

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

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

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

答案 4 :(得分:1)

在删除了ruby 2.2版本的符号GC之后,现在,凡人符号,即当我们将字符串转换为符号(“ mortal” .to_sym)时,都会从内存中清除该信息。

检查一下:

require 'objspace'
ObjectSpace.count_symbols
{
  :mortal_dynamic_symbol=>3,
  :immortal_dynamic_symbol=>5,
  :immortal_static_symbol=>3663,
  :immortal_symbol=>3668
}

来源:https://www.rubyguides.com/2018/02/ruby-symbols/