Vector von Objekten der Zugehörigkeit zu einer Eigenschaft
Betrachten Sie den folgenden code:
trait Animal {
fn make_sound(&self) -> String;
}
struct Cat;
impl Animal for Cat {
fn make_sound(&self) -> String {
"meow".to_string()
}
}
struct Dog;
impl Animal for Dog {
fn make_sound(&self) -> String {
"woof".to_string()
}
}
fn main () {
let dog: Dog = Dog;
let cat: Cat = Cat;
let v: Vec<Animal> = Vec::new();
v.push(cat);
v.push(dog);
for animal in v.iter() {
println!("{}", animal.make_sound());
}
}
Der compiler sagt mir, dass v
ist ein Vektor, der Animal
wenn ich versuche zu pushen cat
(type mismatch)
So, wie kann ich einen Vektor der Objekte der Zugehörigkeit zu einer Eigenschaft und ruft die entsprechenden trait-Methode auf jedes element?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vec<Animal>
ist nicht legal, aber der compiler kann nicht sagen, dass Sie da den Typ mismatch irgendwie blendet es. Wenn wir entfernen Sie die Anrufe anpush
, der compiler gibt die folgende Fehlermeldung:Der Grund, warum das nicht legal ist, dass ein
Vec<T>
speichert vieleT
Objekte, die hintereinander im Speicher. AllerdingsAnimal
ist eine Eigenschaft und Eigenschaften haben keine Größe (Cat
und einDog
sind garantiert nicht die selbe Größe haben).Um dieses problem zu lösen, müssen wir etwas lagern, die eine Größe in der
Vec
. Die einfachste Lösung ist, um wickeln Sie die Werte in einerBox
, d.h.Vec<Box<Animal>>
.Box<T>
der eine fixe Größe hat (einen "Fetten" Zeiger", wenn T ist eine Eigenschaft, einen einfachen Zeiger sonst).Hier ist eine funktionierende
main
:Vec
können Sie eineenum
statt (und dann den Zug vielleicht überflüssig). Ansonsten, Nein, Sie können nicht vermeiden, dynamic dispatch. Beachten Sie, dass dynamic dispatch ist nicht von Natur aus böse; es gibt Situationen, in denen es OK ist es zu benutzen!Box<dyn Animal>
.Können Sie einen Referenz-Merkmal Objekt
&Animal
zu leihen, die Elemente und speichern diese Eigenschaft von Objekten in einemVec
. Sie können dann zählt es auf, und verwenden Sie die trait-Schnittstelle.Änderung der
Vec
's generischer Typ, indem ein&
vor der trait funktioniert:Dies ist ideal, wenn Sie wollen, kann die ursprüngliche variable zu halten Eigentums-und wiederzuverwenden.
Denken Sie daran, mit dem oben beschriebenen Szenario können Sie nicht das Eigentum an
dog
odercat
weil dieVec
hat sich mit dieser konkreten Instanzen im gleichen Umfang.Einführung in einen neuen Bereich kann helfen, behandeln, die insbesondere die situation: