Struct用起来很顺手。Struct看起来像是一个简单的类,我也一直把它当类来用。但其实它和一般的类不太一样。

Struct

有些时候,我们需要把一些属性放在一起,但又不需要给它一些特殊方法,这个时候我们可以选择Struct。这种场景在算法中最常见。

equal

这个地方需要注意。Struct的equal同class的默认equal不同。class的默认equal,只有是同一个对象相等,才会返回true。今天写算法的时候就被坑在这了,补了测试,才发现问题。
而Struct的,只要值相等,就会返回true,代码如下:

class Foo
  attr_accessor :a
  def initialize(a)
    self.a = a
  end
end
f1 = Foo.new("foo")
f2 = Foo.new("foo")
f1 == f2 # => false

Bar = Struct.new(:a)
b1 = Bar.new("bar")
b2 = Bar.new("bar")
b1 == b2 # => true

构建方式

Struct.new("Customer", :name, :address)    #=> Struct::Customer
Struct::Customer.new("Dave", "123 Main")   #=> #<struct Struct::Customer name="Dave", address="123 Main">

# Create a structure named by its constant
Customer = Struct.new(:name, :address)     #=> Customer
Customer.new("Dave", "123 Main")

个人更喜欢第二种。

accessor

b1.a, b1[:a], b1["a"], b1[0]
我们可以看到,struct非常灵活的。

members, values

b1.members
# => [:a]

b1.values
# => ["bar"]

遍历(each, each_pair) && select

b1.each {|value| puts value }
b1.each_pair {|name, value| puts("#{name} => #{value}") }

Lots = Struct.new(:a, :b, :c, :d, :e, :f)
l = Lots.new(11, 22, 33, 44, 55, 66)
l.select {|v| (v % 2).zero? }   #=> [22, 44, 66]

总结

  1. 平时要读读文档,要不然会被坑(==)。要写测试,测试可以帮助我们发现问题。

  2. struct比想象中要方便。

参考

Ruby doc


2dian718
108 声望4 粉丝

引用和评论

0 条评论