Struct && OpenStruct

1 Struct
本质上是一个简单的类,它允许你在不用定义class的情况下封装属性和accessor方法。

Bonus = Struct.new(:score,:per_score,:rate)  do
  def bonus
    self.score*self.rate*self.per_score
  end
end
user1_bonus = Bonus.new(12,2,0.5)
user1_bonus.bonus #12

Struct 需要开头明确声明字段

user1_bonus.rate = 1
user1_bonus.rate #1
user1_bonus.bonus #24
user1_bonus.name= 'dong' # undefined method `name=' for #

 user1_bonus.to_json
 => "{\"score\":12,\"per_score\":2,\"rate\":0.5}" 
user1_bonus.to_h
 => {:score=>12, :per_score=>2, :rate=>0.5} 
Bonus.ancestors
 => [Bonus, Struct, Enumerable, Object, Kernel, BasicObject] 
Class.ancestors
[Class, Module, Object, Kernel, BasicObject] 

Struct 继承了 Enumerable,可以

 user1_bonus.each{|x| puts x}
12
2
0.5

优点:定义简便,结构清晰;只能调用定义好的,相比Hash不容易出错;ruby内置,直接使用;C实现,性能较好

2 OpenStruct
OpenStruct是一个类似Hash的数据结构,它允许我们使用对象自带的值定义任意的属性,相比hash可以 point调用,可动态添加属性;OpenStruct 是 Ruby 标准库内, Ruby 实现

require 'ostruct' #需要
a = OpenStruct.new name: 'dong',age: 12
OpenStruct.ancestors
 => [OpenStruct, ActiveSupport::ToJsonWithActiveSupportEncoder, Object, PP::ObjectMixin, JSON::Ext::Generator::GeneratorMethods::Object, ActiveSupport::Tryable, ActiveSupport::Dependencies::Loadable, Kernel, BasicObject] 

a.to_h
 => {:name=>"dong", :age=>12} 
a.to_json
 => "{\"table\":{\"name\":\"dong\",\"age\":12}}" 
a.each{|x| puts x}
 => nil 

你可能感兴趣的:(Struct && OpenStruct)