使用HashWithIndifferentAccess时字符串与符号?

时间:2016-12-06 21:09:42

标签: ruby-on-rails ruby-on-rails-4

我在Ruby in Rails 4.0中学习Rails能够使用类HashWithIndifferentAccess通过可以是符号或字符串的键来引用哈希值。例如,params哈希可以通过符号或字符串引用,因为它使用类HashWithIndifferentAccess

即:params["id"] and params[:id] --> both access the id in the params hash

虽然两者都可以使用并且可以被Rails接受,但是出于最佳实践/性能原因,是否明显优于其他?我最初的想法是,使用符号会更好,因为一旦存储它们,它们就会保留那段记忆。这与字符串形成对比,每个字符串都需要一个新的内存。

这是对的吗?或者是否使用字符串或符号真的无关紧要?

2 个答案:

答案 0 :(得分:1)

Ruby Strings是可变的,可能带来一些不可预测性和降低的性能。由于这些原因,Ruby还提供了符号选择。最大的区别是符号是不可变的。虽然可以更改可变对象,但只能覆盖不可变对象。符号可以更好地利用内存,从而提高性能,但如果不够小心,应用程序的内存占用量将会增加。

使用字符串或符号归结为理解这两个术语以及它们如何为整体应用程序运行状况和性能提供服务。这就是为什么可能没有严格定义String的使用位置和Symbol的原因。

我可能会给出的建议是什么:

  • 符号 - 内部标识符,无意更改的变量
  • 字符串 - 正在更改或打印的变量

HashWithIndifferentAccess最终将所有符号内部映射到字符串。

h = ActiveSupport::HashWithIndifferentAccess.new(test: 'test')

如果您尝试检索创建的散列(h)的键,您将获得键作为字符串

h.keys # => ["test"]

答案 1 :(得分:0)

一对亮点:

首先,从Ruby 2.3开始,字符串不变性(具有相同内容的对象指向内存中的相同位置)是一个选项。据我所知,这个功能将成为Ruby 3.0的默认功能。这是一个例子:

# frozen_string_literal: true

a = 'foo'
b = 'foo'

puts a.object_id
puts b.object_id

puts a.equal?(b)

运行文件:

➜  ruby test.rb  
70186103229600  
70186103229600  
true

其次,符号通常首选为哈希键(请参阅this popular style指南)。

如果您有兴趣详细了解HashWithIndifferentAccess如何运作,here's a good blog post。简短版本是所有键都在幕后转换为字符串。