【问题标题】:Why even use Strings in hashes if symbols exist如果符号存在,为什么还要在哈希中使用字符串
【发布时间】:2017-01-06 23:50:42
【问题描述】:

如果使用符号,我为什么要使用字符串 1) 节省内存 2) 具有更好的访问时间

我看到代码中有时使用字符串,有时使用符号。为什么要选择具有符号所有优点的字符串?

好的,您的访问键通常不是字符串,因此您总是需要输入强制转换。但是,为什么转换不会隐式发生呢?

【问题讨论】:

  • 当引用键的东西总是以字符串开头时,我认为值得将它们保留为字符串。另外,我最近不得不使用整数作为键。他们无法转换为符号(据我所知)。
  • 将数字作为键其实是个好点
  • 你知道钥匙可以是任何东西,对吧?类、字符串、数组、哈希、符号、procs……为什么要对字符串做一个特殊的例外?
  • 不,我没有,谢谢你的信息

标签: ruby


【解决方案1】:

我看到代码中有时使用字符串,有时使用符号。为什么要选择具有符号所有优点的字符串?

在 Ruby 2.2 中添加 Symbol GC 之前,在运行时生成符号会导致长时间运行的应用程序出现内存泄漏。使用字符串是绕过这个内存问题并获得 gc 的一种方法,它在 ruby​​ 生态系统中徘徊。使用冻结字符串支持,在某些时候符号和字符串将是相同的。

好的,您的访问键通常不是字符串,因此您总是需要输入强制转换。但是,为什么转换不会隐式发生呢?

哈希将一个对象映射到一个对象。这个:

{"a"=>1, :a=>1}

是一个有效的哈希。

如果你想隐式转换,你可以使用 ActiveSupport 的HashWithIndifferentAccess

【讨论】:

  • 在哪种情况下,您希望使用 "a" 和 :a 访问密钥 .. 听起来更像是一个前卫的边缘情况,导致的麻烦多于解决的问题
  • 最后一句话具有误导性“在冻结字符串支持的情况下,在某些时候符号和字符串将是相同的”——符号和不可变字符串之间存在很大差异,保证只有一个实例:abc"abc" 的实例可能有很多,因此将字符串转换为符号的运行时间也很重要。在某些应用程序中,这仍然是首选字符串键的一个非常有效的论点。
  • @akuhn 使用 freeze-string pragma,相同值的不可变字符串是同一个对象。见:crivelaro.me/programming/2016/01/01/…
  • 它没有,试试a = 'hello'; b = 'world'; 10.times { p (a + b).freeze.object_id } 这篇博文信息不灵通且具有误导性。
  • @akuhn 答案是正确的。冻结字符串编译指示与仅冻结字符串不同。这是您放在文件顶部的特殊注释 (# frozen_string_literal: true),默认情况下会冻结所有字符串文字。这个 prama 确实会导致具有相同值的字符串文字成为相同的对象。在 Ruby 的某些未来版本中,pragma 将成为默认值:这就是答案的含义,即“使用冻结的字符串支持,在某些时候符号和字符串将是相同的。”
【解决方案2】:

有不同的权衡,

  • 符号最适合用于一组有界键,理想情况下仅限于源代码中的值。
  • 字符串最适合用于从用户输入或其他外部来源获取的无限制键集,例如在处理非结构化 JSON 数据时。

为什么?

在 Ruby 2.2 之前,符号不会被垃圾收集,并且处理无限的键集显然会导致内存泄漏。但是即使使用garage collection,仍然需要“实习”所有字符串输入以将它们转换为符号的巨大成本。因此,如果您的代码无论如何都使用来自文本文件或网络的字符串,那么只使用字符串键可能是最聪明的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-23
    • 2018-10-02
    • 2012-01-01
    • 2016-07-30
    • 2012-10-31
    • 2011-08-29
    • 2017-12-21
    • 1970-01-01
    相关资源
    最近更新 更多