Как преобразовать черту в конкретный тип?

У меня есть трейт-объект, и я хочу знать конкретный объект, на который он указывает, но я не могу понять, как получить этот конкретный объект.

Я хочу что-то вроде следующего:

trait MyClonable {
   /** copy from another MyClonable */
   fn my_clone_from(&mut self, other: &Self)->Result<(), MyError>;
}

impl MyClonable for SomeType {
   fn my_clone_from(&mut self, other: &MyClonable)->Result<(), MyError> {...}
}

Чтобы я мог сказать что-то вроде:

let mut new_thing = SomeType::new();
new_thing.my_clone_from(&old_thing)?;

Тогда new_thing будет содержать своего рода копию old_thing, если только old_thing не имеет неожиданного типа, и в этом случае он должен возвращать ошибку.

Но Rust не позволит мне получить что-то вроде Option<&SomeType> из MyClonable.


person Martin Ellison    schedule 15.01.2020    source источник


Ответы (1)


Вы не можете. Трейт-объект дает вам доступ только к трейт-методам. Вам нужно будет вручную указать, какой конкретный тип следует понижать, как описано в этом QA: Как получить ссылку на конкретный тип из типаж-объекта?.

Затем вы можете попробовать выполнить понижающее приведение к каждому из ваших известных типов, пока один из них не добьется успеха, но это грязно.

Вместо этого лучше использовать дженерики:

trait MyClonable<T> {
    fn my_clone_from(&mut self, other: &T);
}

И теперь вы можете реализовать этот трейт для всех ваших поддерживаемых типов:

impl MyClonable<u32> for i32 {
    fn my_clone_from(&mut self, _other: &u32) { }
}

impl MyClonable<Tomato> for i32 {
    fn my_clone_from(&mut self, _other: &Tomato) { }
}
person sshashank124    schedule 15.01.2020