首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >什么时候在Ruby中使用Struct而不是Hash?

什么时候在Ruby中使用Struct而不是Hash?
EN

Stack Overflow用户
提问于 2010-07-18 20:59:32
回答 5查看 19.5K关注 0票数 75

我没有多少编程经验。但是,在我看来,Struct似乎有点类似于Hash。

  • 什么结构可以做得很好?
  • 有没有什么结构可以做,而哈希不能做?

在googling上搜索后,Struct的概念在C中很重要,但我对C了解不多。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2010-07-18 21:10:43

Structs与使用hashmaps有以下不同之处(除了代码的外观之外):

  • 结构有一组固定的属性,而您向散列中添加了新的键。
  • 调用在结构的实例上不存在的属性将导致NoMethodError,而从散列中获取不存在的键的值将只返回nil。
  • 不同结构的两个实例永远不会相等,即使结构具有相同的属性并且实例具有相同的值(即Struct.new(:x).new(42) == Struct.new(:x).new(42)为false,而Foo = Struct.new(:x); Foo.new(42)==Foo.new(42)为true)。
  • 结构的to_a方法返回一个值数组,虽然散列上的to_a会得到键值对的数组(其中“

”表示“双元素数组”),但

  • 如果为Foo = Struct.new(:x, :y, :z),则可以执行Foo.new(1,2,3)来创建Foo的实例,而不必拼写属性名称。

所以回答这个问题:当你想用一组已知的属性来建模对象时,使用structs。当你想任意使用hashmap建模时(例如,计算每个单词在字符串中出现的频率或将昵称映射为全名等肯定不是结构的工作,而使用姓名、年龄和地址建模一个人将非常适合Person = Struct.new(name, age, address))。

作为附注:C结构与ruby结构几乎没有关系,所以不要让自己对此感到困惑。

票数 102
EN

Stack Overflow用户

发布于 2015-07-09 18:33:52

我知道这个问题几乎得到了很好的回答,但令人惊讶的是,没有人谈到Struct最大的区别之一和真正的好处。我猜这就是为什么somebody is still asking

我理解其中的区别,但是当Hash可以做同样的事情并且更容易处理时,使用Struct而不是Hash的真正优势是什么?似乎Struct是一种多余的东西。

Structfaster

代码语言:javascript
复制
require 'benchmark'

Benchmark.bm 10 do |bench|
  bench.report "Hash: " do
    50_000_000.times do { name: "John Smith", age: 45 } end
  end

  bench.report "Struct: " do
    klass = Struct.new(:name, :age)
    50_000_000.times do klass.new("John Smith", 45) end
  end

end

# ruby 2.2.2p95 (2015-04-13 revision 50295) [x64-mingw32].
#                 user     system      total        real
# Hash:       22.340000   0.016000  22.356000 ( 24.260674)
# Struct:     12.979000   0.000000  12.979000 ( 14.095455)

# ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin11.0]
# 
#                  user     system      total        real
# Hash:       31.980000   0.060000  32.040000 ( 32.039914)
# Struct:     16.880000   0.010000  16.890000 ( 16.886061)
票数 47
EN

Stack Overflow用户

发布于 2015-10-21 07:57:30

另一个主要区别是您可以将行为方法添加到Struct中。

代码语言:javascript
复制
 Customer = Struct.new(:name, :address) do

  def greeting; "Hello #{name}!" ; end

end

Customer.new("Dave", "123 Main").greeting  # => "Hello Dave!"
票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3275594

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档