很多时候人们在 Ruby 哈希中使用符号作为键。
与使用字符串相比有什么优势?
例如:
hash[:name]
对比
hash['name']
TL;博士:
使用符号不仅可以节省比较时间,还可以节省内存,因为它们只存储一次。
Ruby 符号是不可变的(无法更改),这使得查找内容变得更加容易
简短(ish)答案:
Ruby 中的符号 基本上是 “不可变字符串” .. 这意味着它们不能更改,这意味着在整个源代码中多次引用相同的符号时,始终存储为相同的实体,例如具有相同的对象 id .
另一方面,字符串是可变的 ,它们可以随时更改。这意味着 Ruby 需要将您在整个源代码中提到的每个字符串存储在它的单独实体中,例如,如果您在源代码中多次提到一个字符串“名称”,那么 Ruby 需要将这些全部存储在单独的 String 对象中,因为它们以后可能会改变(这是 Ruby 字符串的本质)。
如果您使用字符串作为哈希键,Ruby 需要评估字符串并查看其内容(并在其上计算哈希函数)并将结果与已存储在哈希中的键的(哈希)值进行比较.
如果您使用符号作为哈希键,则暗示它是不可变的,因此 Ruby 基本上可以将对象 ID 的(哈希函数)与已经存储在中的键的(哈希)对象 ID 进行比较哈希。(快多了)
缺点: 每个符号都占用 Ruby 解释器符号表中的一个槽,该槽永远不会被释放。符号永远不会被垃圾收集。因此,极端情况是当您拥有大量符号(例如自动生成的符号)时。在这种情况下,您应该评估这如何影响您的 Ruby 解释器的大小。
笔记:
如果您进行字符串比较,Ruby 可以仅通过比较它们的对象 id 来比较符号,而无需评估它们。这比比较需要评估的字符串快得多。
如果您访问散列,Ruby 总是应用散列函数从您使用的任何键计算“散列键”。您可以想象像 MD5 哈希这样的东西。然后 Ruby 将这些“散列键”相互比较。
每次在代码中使用字符串时,都会创建一个新实例 - 创建字符串比引用符号要慢。
从 Ruby 2.1 开始,当您使用冻结字符串时,Ruby 将使用相同的字符串对象。这避免了必须创建相同字符串的新副本,并将它们存储在垃圾收集的空间中。
长答案:
https://web.archive.org/web/20180709094450/http://www.reactive.io/tips/2009/01/11/the- difference-between-ruby-symbols-and- strings
http://www.randomhacks.net.s3-website-us- east-1.amazonaws.com/2007/01/20/13-ways-of-looking-at-a-ruby- symbol/
https://www.rubyguides.com/2016/01/ruby- mutability/