为什么:Ruby中的key.hash!='key'.hash?

And*_*Dog 0 ruby hash dictionary rhodes

我正在为Rhodes移动应用程序框架学习Ruby 并遇到了这个问题:Rhodes的HTTP客户端将JSON响应解析为Ruby数据结构,例如

puts @params # prints {"body"=>{"results"=>[]}}
Run Code Online (Sandbox Code Playgroud)

由于键"body"在这里是一个字符串,我的第一次尝试@params[:body]失败了(是nil),而它必须是@params['body'].我发现这是最不幸的.

有人可以解释为什么字符串和符号有不同的哈希值,即:body.hash != 'body'.hash在这种情况下?

Ser*_*sev 6

符号和字符串有两个不同的用途.

字符串是你熟悉的老朋友:可变和垃圾收集.每次使用字符串文字或#to_s方法时,都会创建一个新字符串.您使用字符串来构建HTML标记,将文本输出到屏幕等等.

另一方面,符号是不同的.每个符号仅存在于一个实例中,并且始终存在(即,它不是垃圾收集的).因此,你应该非常小心(String#to_sym:''文字)制作新的符号.这些属性使它们成为命名事物的良好候选者.例如,在宏中使用符号是惯用的attr_reader :foo.

如果您从外部源获取哈希(例如,您反序列化了JSON响应)并且您希望使用符号来访问其元素,那么您可以使用HashWithIndifferentAccess(如其他人指出的那样),或者从ActiveSupport调用帮助器方法:

require 'active_support/core_ext'

h = {"body"=>{"results"=>[]}}
h.symbolize_keys # => {:body=>{"results"=>[]}}
h.stringify_keys # => {"body"=>{"results"=>[]}}
Run Code Online (Sandbox Code Playgroud)

请注意,它只会触及顶级,不会进入子哈希.