为什么:key.hash!='Ruby中的密钥哈希?

为什么:key.hash!='Ruby中的密钥哈希?,ruby,hash,dictionary,rhodes,Ruby,Hash,Dictionary,Rhodes,我现在正在学习Ruby的移动应用程序框架,遇到了这个问题:Rhodes的HTTP客户端将JSON响应解析为Ruby数据结构,例如 puts @params # prints {"body"=>{"results"=>[]}} 因为这里的键体是一个字符串,所以我的第一次尝试@params[:body]失败是nil,它必须是@params['body']。我觉得这很不幸 有人能解释为什么字符串和符号有不同的散列,例如:body.hash!='body.hash在本例中?在Rails中,

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

puts @params # prints {"body"=>{"results"=>[]}}
因为这里的键体是一个字符串,所以我的第一次尝试@params[:body]失败是nil,它必须是@params['body']。我觉得这很不幸


有人能解释为什么字符串和符号有不同的散列,例如:body.hash!='body.hash在本例中?

在Rails中,params散列实际上是一个HashWithInferenceTaccess,而不是一个标准的ruby散列对象。这允许您使用“action”之类的字符串或:action之类的符号来访问内容

无论使用什么,都会得到相同的结果,但请记住,这只适用于具有无差异访问对象的哈希


复制自:

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

字符串是您熟悉的好朋友:可变和垃圾回收。每次使用字符串文字或to_方法时,都会创建一个新字符串。您可以使用字符串构建HTML标记,将文本输出到屏幕等等

另一方面,符号是不同的。每个符号只存在于一个实例中,并且始终存在,即它不是垃圾收集的。因此,您应该非常小心地创建新符号Stringto_sym和:literal。这些属性使它们成为命名事物的良好候选对象。例如,在宏(如attr_reader:foo)中使用符号是惯用的

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

require 'active_support/core_ext'

h = {"body"=>{"results"=>[]}}
h.symbolize_keys # => {:body=>{"results"=>[]}}
h.stringify_keys # => {"body"=>{"results"=>[]}}

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

符号和字符串永远不会=:

这是一个非常合理的设计决策。毕竟,它们有不同的类和方法,一个是可变的,另一个不是可变的,等等

因此,必须确保它们永远不是eql?:

两个不是eql的对象?通常没有相同的散列,但即使有,散列查找也使用散列,然后使用eql?。所以你的问题是为什么符号和字符串不是eql


Rails使用HashWithInferenceTaccess,通过字符串或符号进行无差别访问。

因为它们是不同的对象:您应该在注释中发布此链接。复制粘贴帖子很糟糕。实际上我刚刚获得了评论权限。。。从下一次开始会小心的。。。谢天谢地,塞吉奥,这归结为同一个问题,为什么他们不平等?它们不是主要用于相同的目的吗?但符号不是仅用于命名参数和字典键吗?如果是,它们也可以具有与相应字符串相同的散列。还有哪些地方使用了符号?@AndiDog:我想,这会带来更多的混乱,而不是解决问题。混乱是不好的。你的问题很容易解决。
:foo == 'foo'  # => false
:foo.eql? 'foo'  # => false