首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么符号不是冻结的字符串?

为什么符号不是冻结的字符串?
EN

Stack Overflow用户
提问于 2012-06-18 23:01:39
回答 6查看 2.9K关注 0票数 29

我理解字符串和符号在理论上的区别。我知道符号是用来表示一个概念、一个名字、一个标识符、一个标签或一个键,而字符串就是一大堆字符。我知道字符串是可变的和暂时的,其中符号是不可变的和永久的。我甚至喜欢我的文本编辑器中符号与字符串的不同之处。

让我困扰的是,实际上,符号与字符串是如此相似,以至于它们没有被实现为字符串的事实导致了很多令人头疼的问题。它们甚至不支持鸭子类型或隐式强制,不像其他著名的“相同但不同”的组合,Float和Fixnum。

当然,最大的问题是从其他地方进入Ruby的散列,比如JSON和HTTP CGI,使用的是字符串键,而不是符号键,所以Ruby程序必须竭尽全力提前或在查找时转换这些散列。仅仅是HashWithIndifferentAccess的存在,以及它在Rails和其他框架中的广泛使用,就表明这里存在一个问题,一个需要解决的问题。

谁能告诉我为什么符号不应该是冻结字符串的实际原因?而不是“因为它总是这样做”(历史上)或“因为符号不是字符串”(恳求问题)。

考虑以下令人惊讶的行为:

代码语言:javascript
复制
:apple == "apple"  #=> false, should be true

:apple.hash == "apple".hash #=> false, should be true

{apples: 10}["apples"]  #=> nil, should be 10

{"apples" => 10}[:apples]  #=> nil, should be 10

:apple.object_id == "apple".object_id #=> false, but that's actually fine

要让下一代this开发者不那么困惑,只需这样做:

代码语言:javascript
复制
class Symbol < String
  def initialize *args
    super
    self.freeze
  end

(还有许多其他库级别的黑客攻击,但仍然不是太复杂)

另请参阅:

更新:我认为Matz在这里为class Symbol < String做了很好的解释:http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/9192 (感谢Azolo挖掘了这一点,也感谢Matz的最终撤回)。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2012-06-18 23:52:02

这个答案与我的original answer截然不同,但我在Ruby邮件列表上遇到了一对interesting threads。(两本书都读得很好)

因此,在2006年的某个时候,matz将Symbol类实现为Symbol < String。然后,Symbol类被剥离,以删除所有的可变性。所以Symbol实际上是一个不可变的String

然而,它被恢复了。The reason given was

尽管它是高度反对DuckTyping的,但人们倾向于在类上使用case,而Symbol < String通常会导致严重的问题。

所以你的问题的答案仍然是:Symbol类似于String__,但它不是。

问题不是Symbol不应该是String,而是它在历史上不是。

票数 9
EN

Stack Overflow用户

发布于 2012-06-18 23:09:03

我不知道完整的答案,但这里有一个很大的部分:

使用符号作为散列键的原因之一是给定符号的每个实例都是完全相同的对象。这意味着:apple.id将始终返回相同的值,即使您没有传递它。另一方面,"apple".id每次都会返回一个不同的id,因为会创建一个新的string对象。

这就是为什么建议将符号作为散列键的原因。当使用符号时,不需要进行对象等价性测试。它可以直接短路到对象标识。

票数 5
EN

Stack Overflow用户

发布于 2012-06-20 07:47:07

另一个需要注意的问题是,"apple".each_char是有意义的,但是:apple.each_char没有。字符串是“字符的有序列表”,而符号是没有显式值的原子数据点。

我要说的是,HashWithIndifferentAccess实际上证明了Ruby符号扮演着两种不同的角色:符号(本质上类似于其他语言中的枚举)和内部字符串(本质上是抢占式优化,弥补了ruby被解释为没有智能优化编译器的好处)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11085564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档