为什么没有符号的字符串冻结?(Why are symbols not frozen strings?

2019-07-30 00:37发布

我理解字符串和符号之间的理论差异。 据我所知,符号旨在代表一个概念或一个名称或标识或标签或键,字符串是字符的包。 据我所知,字符串是可变的,短暂的,其中的符号是不可变的和永久的。 我甚至喜欢的符号如何在我的文字编辑器中查看不同的字符串。

让我困扰的是,实际上来说,符号是如此的相似字符串的事实,他们不是作为字符串实现会导致很多麻烦。 他们甚至不支持鸭打字或暗示的胁迫,不像其他著名的“相同,但不同的”夫妇,浮球Fixnum对象。

最大的问题,当然,是哈希进入红宝石从其他地方一样,JSON和HTTP CGI,使用字符串键,而不是符号键,因此Ruby程序必须使出浑身解数要么将这些前面或在查找时间。 仅仅存在HashWithIndifferentAccess ,并在Rails和其他框架及其猖獗的使用,证明了这里有一个问题,需要被划伤痒。

谁能告诉我一个实际原因的符号不应该被冻结的字符串? 除了“因为这是它是如何始终秉行”(历史的)或者“因为符号不是字符串”(乞讨的问题)。

考虑以下惊人的行为:

: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

所有它会采取让下一代Ruby开发者少困惑的是这样的:

class Symbol < String
  def initialize *args
    super
    self.freeze
  end

(和许多其他库级黑客的了,不过,不要太复杂)

也可以看看:

  • http://onestepback.org/index.cgi/Tech/Ruby/SymbolsAreNotImmutableStrings.red
  • http://www.randomhacks.net/articles/2007/01/20/13-ways-of-looking-at-a-ruby-symbol
  • 为什么使用哈希符号的时候,而不是一个散列字符串做我的代码休息?
  • 为什么要使用的符号,Ruby的哈希键?
  • 什么是符号和我们如何使用它?
  • 红宝石VS符号中的字符串哈希
  • 无法获取符号在Ruby中的窍门
  • http://blog.arkency.com/could-we-drop-symbols-from-ruby/
  • 确实存在红宝石的符号,因为字符串是可变的,而不是拘留?

更新:我觉得马茨使得为案例class Symbol < String很好的位置: http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/9192 (感谢唑并挖这件事,也麦茨”最终收回)。

Answer 1:

这个答案从我的截然不同原来的答案 ,但我遇到了一对夫妇有趣的 线程 Ruby的邮件列表上。 (两个好读)

所以,在2006年的一个点,马茨实施的Symbol类的Symbol < String 。 然后Symbol类被剥离下来,以消除任何可变性。 因此,一个Symbol实际上是一个不可改变的String

然而,有人回复。 在给出的理由是

即使是非常反对鸭子类型,人们往往对类使用情况,并且符号<字符串经常导致严重的问题。

所以回答你的问题仍然是: 一个Symbol就像是一个String ,但事实并非如此。
这个问题是不是一个Symbol不应该是String ,而是它在历史上并非如此。



Answer 2:

我不知道一个完整的答案,但这里是它的一个重要组成部分:

一的该符号被用于散列键的原因是,一个给定的符号的每个实例是完全相同的对象。 这意味着:apple.id总是会返回相同的值,即使你不及格它周围。 在另一方面, "apple".id将每次返回不同的ID,因为创建一个新的字符串对象。

这种差异就是符号被推荐为哈希键。 无对象等同性测试需要使用符号时完成。 它可以是短路的直接对象标识。



Answer 3:

另一个考虑是, "apple".each_char是有道理的,但是:apple.each_char没有。 的字符串是“字符的有序列表”,而是一个符号是原子数据点,没有明确的价值。

我想说的是HashWithIndifferentAccess实际上表明,Ruby的符号是实现两个不同的角色; 符号 (这基本上就像在其他语言中枚举)和实习字符串 (这基本上是一个先发制人的优化,补偿的事实,红宝石演绎得如此不具有智能优化的编译器的好处。)



Answer 4:

看到这个答案: https://stackoverflow.com/a/6745253/324978

主要理由:性能(符号存储为整数,并且永远不会被垃圾收集)和一致性( :admin:admin总是指向同一个对象,其中"admin""admin"没有这样的担保)等。



Answer 5:

它的基本功能是,这些不应该是真实的:

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

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

符号总是相同的对象和文本不是。



Answer 6:

如果在所有的String可以继承的象征,因为它增加了很多功能(变异)。 但是,一个符号不能用“是”字符串,因为在将需要的突变,它会失败的所有情况。

在任何情况下,正如我上面所说,串==符号绝不如上面已经建议返回true。 如果你想一下这个,你会发现,就不可能有合理的实现==,其中考虑了子类的实例,以及一类。



文章来源: Why are symbols not frozen strings?
标签: ruby symbols