Ruby Struct Equal

2dian718發表於2019-02-16

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

相關文章