我刚开始阅读本书Eloquent Ruby,我已经到了关于Ruby中符号的章节。
Ruby中的字符串是可变的,这意味着每个字符串都会分配内存,因为内容可以更改,即使内容相同。如果我需要Java中的可变字符串,我会使用StringBuffer。但是,由于常规Java字符串是不可变的,因此一个String对象可以由多个引用共享。因此,如果我有两个带有“Hello World”内容的常规字符串,则两个引用都指向同一个对象。
Ruby中Symbols的目的是否与Java中的“普通”String对象相同?它是程序员优化内存的一个特性吗?
我写的东西是真的吗?或者我误解了符号的概念?
答案 0 :(得分:5)
符号在Ruby中接近字符串,但它们并不等同于常规Java字符串,尽管它们也有一些共性,例如不变性。但是存在细微的差别 - 获得对符号的引用有多种方法(稍后将详细介绍)。
在Ruby中,完全可以来回转换这两个。 String#to_sym将String转换为Symbol,而Symbol#to_s将Symbol转换为String。那么区别是什么呢?
引用符号的RDoc:
在程序执行期间,将为给定的名称或字符串创建相同的Symbol对象,无论该名称的上下文或含义如何。
符号是唯一标识符。如果Ruby解释器第一次绊倒让我们说:mysymbol
,那么会发生什么:在内部,如果它还不存在,则符号存储在表中(非常类似于解析器使用的“符号表”) ;这发生在CRuby / MRI中使用C函数rb_intern
,否则Ruby将查找表中的现有值并使用它。在创建符号并将其存储在表中之后,从那时起,无论您何时引用符号:mysymbol
,您都将获得相同的对象,即存储在该表中的对象。
考虑这段代码:
sym1 = :mysymbol
sym2 = "mysymbol".to_sym
puts sym1.equal?(sym2) # => true, one and the same object
str1 = "Test"
str2 = "Test"
puts str1.equal?(str2) # => false, not the same object
注意区别。它说明了Java Strings和Ruby Symbols之间的主要区别。如果你想在Java中使用Strings的对象相等,那么只有比较完全相同的String引用才能实现它,而在Ruby中,可以通过多种方式获得对Symbol的引用,如上例所示。
Symbols的独特性使它们成为哈希中的完美键:与常规字符串相比,查找性能得到了提升,因为您不必显式地对键进行哈希处理,因为您可以简单地使用符号的唯一性直接查找的标识符。通过编写:somesymbol
,你告诉Ruby“给我一个你存储在标识符'somesymbol'下面的东西”。因此,当您需要在以下内容中进行唯一标识时,符号是您的首选:
但是,正如Jim Weirich在下面的文章中指出的那样,符号不是字符串,甚至不是鸭子打字的意思。你不能连接它们或检索它们的大小或从它们获得子串(除非你首先将它们转换为字符串,即)。因此,使用字符串的问题很简单 - 正如Jim所说:
在需要时使用字符串...嗯......类似字符串的行为。
关于该主题的一些文章:
答案 1 :(得分:1)