Ich schrieb ein Programm, das trait Animal
und struct Dog
die Umsetzung der Eigenschaft und struct AnimalHouse
Speichern eines Tieres als Merkmal Objekt Box<Animal>
hat.Wie klonst du eine Struktur, die ein Objekt speichert?
trait Animal{
fn speak(&self);
}
struct Dog{
name: String
}
impl Dog{
fn new(name: &str) -> Dog {
return Dog{name: name.to_string()}
}
}
impl Animal for Dog{
fn speak(&self){
println!{"{}: ruff, ruff!", self.name};
}
}
struct AnimalHouse{
animal: Box<Animal>
}
fn main(){
let house = AnimalHouse{animal: Box::new(Dog::new("Bobby"))};
house.animal.speak();
}
Es funktioniert perfekt und gibt "Bobby: Halskrause, Halskrause!" wie erwartet.
Aber wenn ich versuche, house
zu klonen der Compiler gibt Fehler
fn main(){
let house = AnimalHouse{animal: Box::new(Dog::new("Bobby"))};
let house2 = house.clone()
house2.animal.speak();
}
32:31 error: type `AnimalHouse` does not implement any method in scope named `clone` let house2 = house.clone(); ^~~~~~~ 32:31 help: methods from traits can only be called if the trait is implemented and in scope; the following trait defines a method `clone`, perhaps you need to implement it: 32:31 help: candidate #1: `core::clone::Clone` error: aborting due to previous error
Ich versuchte #[derive(Clone)]
vor struct AnimalHouse
hinzufügen und bekam einen anderen Fehler:
24:24 error: the trait `core::marker::Sized` is not implemented for the type `Animal` [E0277] animal: Box ^~~~~~~~~~~~~~~~~~~ 22:15 note: in expansion of #[derive_Clone] 22:15 note: expansion site 24:24 note: `Animal` does not have a constant size known at compile-time animal: Box ^~~~~~~~~~~~~~~~~~~ 22:15 note: in expansion of #[derive_Clone] 22:15 note: expansion site 24:24 error: the trait `core::clone::Clone` is not implemented for the type `Animal` [E0277] animal: Box ^~~~~~~~~~~~~~~~~~~ 22:15 note: in expansion of #[derive_Clone] 22:15 note: expansion site error: aborting due to 2 previous errors
So wie die Struktur zu machen Animal House
klonierbar? Ist es für Rost normal, ein Merkmalsobjekt aktiv (im Allgemeinen) zu benutzen?
Die Verwendung von 'clone_box' als Methode für das Merkmal selbst ist ziemlich ineffizient und erfordert von allen Implementierern, dass es auf die gleiche Weise implementiert wird. Eine bessere Lösung ist es, dies als ein "Tier" -Supertrait mit einer pauschalen Implementierung für "T: Animal + Clone" zu haben. * Dies ist der Ansatz, der in Dingen wie AnyMap verwendet wird. –
@ChrisMorgan: Gute Idee; geändert. –