当我在about_hashes.rb年遇到这个问题时,我正经历Ruby Koans tutorial series次:

def test_default_value_is_the_same_object
  hash = Hash.new([])

  hash[:one] << "uno"
  hash[:two] << "dos"

  assert_equal ["uno", "dos"], hash[:one]
  assert_equal ["uno", "dos"], hash[:two]
  assert_equal ["uno", "dos"], hash[:three]

  assert_equal true, hash[:one].object_id == hash[:two].object_id
end

assert_equals中的值实际上是教程所期望的.但我不明白使用<<运算符和=运算符之间有什么区别?

我的期望是:

  • hash[:one]等于["uno"]
  • hash[:two]等于["dos"]
  • hash[:three]等于[]

有人能解释一下为什么我的期望是错误的吗?

推荐答案

当你做hash = Hash.new([])的时候,你正在创建一个散列,它的默认值是所有键的完全相同的数组实例.因此,无论何时访问一个不存在的密钥,都会返回相同的array.

h = Hash.new([])
h[:foo].object_id # => 12215540
h[:bar].object_id # => 12215540

如果希望每个数组有一个Hash.new键,请使用以下语法:

h = Hash.new { |h, k| h[k] = [] }
h[:foo].object_id # => 7791280
h[:bar].object_id # => 7790760

Edit:还要看看Gazler对#<<方法的看法,以及你实际调用它的对象.

Ruby相关问答推荐

当数据包含换行符时,Ruby PKCS7 无法验证

如何在 Ruby 中创建可调用属性

Ruby - 给定一个嵌套数组的数组,如何仅比较每个嵌套数组的最后一个值来找到最大值?

字符串长度多显示一个字符 - ruby

环绕分隔线,保留第一列,最小最终长度

Ruby vs Scala - 各自的优缺点

如何拯救 Ruby 中的 eval?

Ruby 中的 STDIN 和 $stdin 有什么区别?

我应该签入.ruby-gemset和/或.ruby-version吗?

如何使用 Ruby 的邮件 gem 通过 smtp 发送Electron邮件?

用反斜杠单引号替换单引号

在 ruby​​ 中将每个数组元素添加到文件的行中

在Ruby中第一个=符号之后获取子字符串

Ruby 中的 $1 和 \1

我可以使用 `else if` 而不是 `elsif` 吗?

处理来自 Net::HTTP 的异常的最佳方法是什么?

HAML 中 Javascript 中的 Ruby 方法

Mountain Lion rvm 安装 1.8.7 x11 错误

如何在 Ruby 中编写复杂的多行 if 条件?

如何使用 link_to Ruby on rails 添加确认消息