我了解字符串和符号之间的理论区别。我知道符号是用来表示一个概念或一个名称或一个标识符或一个标签或一个键,而字符串是一袋字符。我知道字符串是可变的和瞬态的,而符号是不可变的和永久的。我什至喜欢在我的文本编辑器中符号与字符串的不同之处。
困扰我的是,实际上,符号与字符串非常相似,以至于它们没有作为字符串实现的事实引起了很多头痛。它们甚至不支持鸭式或隐式强制转换,这与另一对著名的“相同但不同”的组合 Float 和 Fixnum 不同。
当然,最大的问题是从其他地方进入 Ruby 的散列,比如 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 中使用符号作为哈希键?
- 什么是符号,我们如何使用它们?
- Ruby 符号与哈希中的字符串
- 无法掌握 Ruby 中的符号
- http://blog.arkency.com/could-we-drop-symbols-from-ruby/
- Ruby 符号是否存在是因为字符串是可变的而不是 intern 的?
更新:我认为 Matz 在class Symbol < String
这里很好地说明了这一点:http: //blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/9192(感谢 Azolo 挖掘了这个,并且Matz 也最终撤回)。