Я написал программу, которая имеет trait Animal
и struct Dog
, реализуя черту и struct AnimalHouse
хранение животного как объекта объекта Box<Animal>
.Как клонировать структуру, сохраняющую объект-объект?
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();
}
Он отлично работает и возвращает «Бобби: ерш, ерш!». как и ожидалось.
Но если я пытаюсь клонировать house
компилятор возвращает ошибку
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
Я пытался добавить #[derive(Clone)]
до того struct AnimalHouse
и получил еще ошибки:
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
Так как сделать-структуру Animal House
cloneable? Это обычный способ для ржавчины активно использовать объект-признак (в общем)?
Помещение 'clone_box' как метода по самому признаку довольно неэффективно, требуя, чтобы все реализаторы реализовали его таким же образом. Лучшее решение состоит в том, чтобы иметь это как супервирт «Животного» с реалистичной реализацией для «T: Animal + Clone». * Это * - это подход, используемый в таких вещах, как AnyMap. –
@ChrisMorgan: Хорошая идея; изменилось. –