Когда использовать Struct вместо хэша в Ruby?
У меня нет большого опыта программирования. Но, на мой взгляд, структура кажется чем-то похожим на хэш.
- что может сделать Struct хорошо?
- есть ли что-нибудь Struct может сделать, что хэш не может сделать?
после googling концепция Struct важна в C, но я мало что знаю о C.
5 ответов:
структуры отличаются от всех HashMap следующими способами (в дополнение к тому, как выглядит код):
- структура имеет фиксированный набор атрибутов, в то время как вы добавляете новые ключи в хэш.
- вызов атрибута, который не существует в экземпляре структуры, вызовет NoMethodError, а получение значения для несуществующего ключа из хэша просто вернет nil.
- два экземпляра разных структур никогда не будут равны, даже если структуры имеют те же атрибуты и экземпляры имеют одинаковые значения (т. е.
Struct.new(:x).new(42) == Struct.new(:x).new(42)имеет значение false, в то время какFoo = Struct.new(:x); Foo.new(42)==Foo.new(42)- Это правда).- The
to_aметод для структуры возвращает массив значений, в то время какto_aна хэше вы получаете массив пар ключ-значение (где "пара" означает "двухэлементный массив")- если
Foo = Struct.new(:x, :y, :z)можно сделатьFoo.new(1,2,3)создать экземплярFooбез необходимости прописывать имена атрибутов.так ответь на вопрос: Когда вы хотите моделируйте объекты с известным набором атрибутов, используйте структуры. Когда вы хотите моделировать произвольное использование хэш-карт (например, подсчет того, как часто каждое слово встречается в строке или сопоставление псевдонимов с полными именами и т. д. это определенно не работа для структуры, в то время как моделирование человека с именем, возрастом и адресом было бы идеально подходит для
Person = Struct.new(name, age, address)).в качестве побочного Примечания: структуры C имеют мало общего с Ruby structs, поэтому не позволяйте себе запутаться в этом.
Я знаю, что этот вопрос был почти хорошо ответил, но удивительно никто не говорил об одном из самых больших различий и реальных преимуществ
Struct. И я думаю, именно поэтому кто - то все еще спрашивает.Я понимаю различия, но в чем реальное преимущество использования структуры над хэшем, когда хэш может делать то же самое, и с ним проще иметь дело? Похоже, что структуры являются своего рода излишними.
Structis быстрее.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)
С Struct документы:
структура-это удобный способ объединить несколько атрибутов вместе, используя методы доступа, без необходимости писать явный класс.
С другой стороны, a хэш:
хэш-это набор пар ключ-значение. Он похож на массив, за исключением того, что индексирование выполняется с помощью произвольных ключей любого типа объекта, а не целочисленного индекса. Порядок который вы пересекаете хэш по ключу или значению, может показаться произвольным и, как правило, не будет в порядке вставки.
основное различие заключается в том, как вы получаете доступ к своим данным.
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короче говоря, вы бы сделали новую структуру, когда вам нужен класс, который является "старые данные" структуры (необязательно с целью расширения его с помощью других методов), и вы будете использовать хэш, когда вам вообще не нужен формальный тип.
еще одно основное отличие заключается в том, что вы можете добавить методы поведения в структуру.
Customer = Struct.new(:name, :address) do def greeting; "Hello #{name}!" ; end end Customer.new("Dave", "123 Main").greeting # => "Hello Dave!"
Если вы просто собираетесь инкапсулировать данные, то хэш (или массив хэшей) в порядке. Если вы планируете манипулировать данными или взаимодействовать с другими данными, то структура может открыть некоторые интересные возможности:
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
Comments