为啥要使用字符串键对符号进行哈希处理
Posted
技术标签:
【中文标题】为啥要使用字符串键对符号进行哈希处理【英文标题】:Why would one use String keys for a hash over symbols为什么要使用字符串键对符号进行哈希处理 【发布时间】:2013-04-25 17:14:43 【问题描述】:这个问题应该是这个问题的反面:Why use symbols as hash keys in Ruby?
如您所见,每个人都同意符号是哈希键最合乎逻辑的选择。但是,我正在使用 sinatra 框架构建一个 Web 应用程序,而 request
对象是一个包含 String
s 作为键的哈希。谁能解释一下为什么这是一种设计选择?
【问题讨论】:
请注意,对于 Sinatra,您可以使用 either a string or a symbol。 “每个人都同意符号是哈希键最合乎逻辑的选择”,不,他们不这样做。这是程序员的选择,有时基于从众本能,但更多时候基于当时最有意义的选择。在字符串和符号之间,我通常使用符号,但我也使用正则表达式模式甚至数组作为键,因为它很方便。 Hash 是一个容器,就像 Array 一样,可以包含各种各样的东西。我们在那里坚持的内容取决于我们,并且应该对那个应用程序有意义。如果我们只讨论 Sinatra 中的参数哈希,请参阅 @Phrogz 答案。 【参考方案1】:因为键的来源——查询字符串——是由字符串组成的,所以在这个字符串中搜索键,通过字符串来索引哈希是最直接方便的。
在 Ruby 运行时创建的每个 Symbol 都被分配并且永远不会被释放。通过发送具有唯一查询字符串参数的数十万个请求,理论上存在(但不太可能)DOS 攻击。如果这些是符号化的,每个请求都会慢慢增加运行时内存池。
另一方面,字符串可能会被垃圾回收。在各种请求中处理的数千个唯一字符串最终会消失,不会产生长期影响。
编辑:请注意,对于Sinatra,符号也可用于访问params
哈希。但是,这是通过创建一个由字符串索引的哈希,并在您发出请求时将符号(在您的代码中)转换为字符串来完成的。除非您执行以下操作:
params.each |key,_| key.to_sym
...您不会受到任何符号伪 DOS 攻击的风险。
【讨论】:
request
对象比查询字符串包含更多内容。 HTTP 标头,例如。由于这些总是相同的,就内存消耗而言,符号似乎是更合乎逻辑的选择。此外,Rack 在任何地方都使用字符串键。
我猜你把params
和request
混淆了?
@MarioDeSchaepmeester 是的,抱歉,我以为您使用的是 Sinatra params
对象。而不是机架request
。
对造成的混乱感到抱歉。我不知道request
属于 Rack。这只是我的第一个 ruby 项目。以上是关于为啥要使用字符串键对符号进行哈希处理的主要内容,如果未能解决你的问题,请参考以下文章