プログラミングの経験はあまりありません。しかし、私にとって、StructはHashにいくらか似ているようです。
グーグルの後、CではStructの概念が重要ですが、Cについてはあまり知りません。
構造体は、次の点で(コードの外観に加えて)ハッシュマップの使用とは異なります。
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
_はキーと値のペアの配列を取得します(「ペア」は「2要素の配列」を意味します)Foo = Struct.new(:x, :y, :z)
の場合、Foo.new(1,2,3)
を実行して、属性名を指定する必要なくFoo
のインスタンスを作成できます。したがって、質問に答えるには、既知の一連の属性を持つオブジェクトをモデル化する場合は、構造体を使用します。任意の使用ハッシュマップをモデル化する場合(たとえば、各Wordが文字列内に出現する頻度をカウントしたり、ニックネームをフルネームにマッピングしたりすることなど)は、構造体の仕事ではありませんが、名前、年齢、住所を使用して人をモデル化すると、 Person = Struct.new(name, age, address)
)に最適です。
補足として:Cの構造体は、Rubyの構造体とはほとんど関係がないので、混乱しないようにしてください。
私はこの質問がほとんど答えられたことを知っていますが、驚くべきことに、Struct
の最大の違いの1つと実際の利点について誰も話していません。そして、それが理由だと思います 誰かがまだ質問しています 。
私は違いを理解していますが、ハッシュが同じことを行うことができ、処理が簡単な場合に、ハッシュよりもStructを使用することの本当の利点は何ですか? Structsは不要なもののようです。
Struct
は速いです。
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)
もう1つの主な違いは、Structに動作メソッドを追加できることです。
Customer = Struct.new(:name, :address) do
def greeting; "Hello #{name}!" ; end
end
Customer.new("Dave", "123 Main").greeting # => "Hello Dave!"
Struct のドキュメントから:
Structは、明示的なクラスを記述せずに、アクセサメソッドを使用して、多数の属性をバンドルする便利な方法です。
一方、 ハッシュ :
ハッシュは、キーと値のペアのコレクションです。これは配列に似ていますが、インデックスは整数のインデックスではなく、任意のオブジェクトタイプの任意のキーを介して行われます。キーまたは値のいずれかでハッシュをトラバースする順序は任意に見える可能性があり、通常は挿入順序ではありません。
主な違いは、データへのアクセス方法です。
Ruby-1.9.1-p378 > Point = Struct.new(:x, :y)
=> Point
Ruby-1.9.1-p378 > p = Point.new(4,5)
=> #<struct Point x=4, y=5>
Ruby-1.9.1-p378 > p.x
=> 4
Ruby-1.9.1-p378 > p.y
=> 5
Ruby-1.9.1-p378 > p = {:x => 4, :y => 5}
=> {:x=>4, :y=>5}
Ruby-1.9.1-p378 > p.x
NoMethodError: undefined method `x' for {:x=>4, :y=>5}:Hash
from (irb):7
from /Users/mr/.rvm/rubies/Ruby-1.9.1-p378/bin/irb:17:in `<main>'
Ruby-1.9.1-p378 > p[:x]
=> 4
Ruby-1.9.1-p378 > p[:y]
=> 5
つまり、 "plain old data"構造 のクラスが必要な場合は新しいStructを作成します(オプションで、より多くのメソッドで拡張する目的で)、次の場合はHashを使用します。正式な型はまったく必要ありません。
データをカプセル化するだけの場合は、ハッシュ(またはハッシュの配列)で問題ありません。データで他のデータを操作または操作することを計画している場合、Structはいくつかの興味深い可能性を開くことができます。
Point = Struct.new(:x, :y)
point_a = Point.new(0,0)
point_b = Point.new(2,3)
class Point
def distance_to another_point
Math.sqrt((self.x - another_point.x)**2 + (self.y - another_point.y)**2)
end
end
puts point_a.distance_to point_b