Je n'ai pas beaucoup d'expérience en programmation. Mais, pour moi, Struct semble un peu similaire à Hash.
Après la recherche sur Google, le concept de Struct est important en C, mais je ne connais pas grand-chose de C.
Les structures diffèrent de l'utilisation de hashmaps des manières suivantes (en plus de l'apparence du code):
Struct.new(:x).new(42) == Struct.new(:x).new(42)
est false, alors que Foo = Struct.new(:x); Foo.new(42)==Foo.new(42)
est true).to_a
pour les structures renvoie un tableau de valeurs, alors que to_a
sur un hachage vous procure un tableau de paires clé-valeur (où "paire" signifie "tableau à deux éléments")Foo = Struct.new(:x, :y, :z)
, vous pouvez utiliser Foo.new(1,2,3)
pour créer une instance de Foo
sans avoir à épeler les noms d'attribut.Donc, pour répondre à la question: lorsque vous souhaitez modéliser des objets avec un ensemble d'attributs connu, utilisez structs. Lorsque vous souhaitez modéliser hashmaps d'utilisation arbitraire (par exemple, compter la fréquence à laquelle chaque mot apparaît dans une chaîne ou mapper des pseudonymes en noms complets, etc. ne sont certainement pas des emplois pour une structure, alors que modéliser une personne avec un nom, un âge et une adresse serait un ajustement parfait pour Person = Struct.new(name, age, address)
).
En tant que sidenote: les structures C n’ont pratiquement rien à voir avec les structures Ruby, ne vous laissez donc pas troubler.
Je sais que la réponse à cette question a été quasiment bonne, mais étonnamment, personne n’a encore évoqué l’une des plus grandes différences et les avantages réels de Struct
. Et je suppose que c'est pourquoi quelqu'un demande toujours .
Je comprends les différences, mais quel est l’avantage réel d’utiliser un Struct sur un hachage, quand un hachage peut faire la même chose, et qu’il est plus simple à gérer? On dirait que les structures sont un peu superflues.
Struct
est plus rapide.
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)
Depuis la Struct documentation:
Une structure est un moyen pratique de regrouper un certain nombre d'attributs, à l'aide de méthodes d'accès, sans avoir à écrire une classe explicite.
D'autre part, un Hash :
Un hachage est une collection de paires clé-valeur. C'est similaire à un tableau, sauf que l'indexation est faite via des clés arbitraires de n'importe quel type d'objet, pas un index entier. L'ordre dans lequel vous parcourez un hachage avec une clé ou une valeur peut sembler arbitraire et ne sera généralement pas dans l'ordre d'insertion.
La principale différence est la manière dont vous accédez à vos données.
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
En bref, vous feriez une nouvelle Struct quand vous voulez une classe qui est une structure "plain old data" (éventuellement avec l'intention de l'étendre avec plus de méthodes), et vous utiliseriez un hachage besoin d'un type formel du tout.
Une autre différence principale est que vous pouvez ajouter des méthodes de comportement à une structure.
Customer = Struct.new(:name, :address) do
def greeting; "Hello #{name}!" ; end
end
Customer.new("Dave", "123 Main").greeting # => "Hello Dave!"
Si vous souhaitez simplement encapsuler les données, un hachage (ou un tableau de hachages) suffit. Si vous envisagez de manipuler les données ou d'interagir avec d'autres données, une structure peut ouvrir certaines possibilités intéressantes:
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