Объекты с изображением - очень странные звери.
Что такое Box<ChildTrait>
? Box<T>
буквально является оберткой для *mut T
. Поэтому Box<ChildTrait>
обертывает *mut ChildTrait
. Потому что ChildTrait
называет черту, ChildTrait
является object type. Указатель на тип объекта представлен парой указателей: указателем на vtable для этого признака и только на этот признак и указателем на фактическое значение.
Когда мы наследуем черту от другого признака, это не значит, что мы можем получить указатель на vtable для первого признака от указателя на vtable для второго признака. Вот почему компилятор жалуется, что
the trait `ParentTrait` is not implemented for the type `ChildTrait`
Мы можем, однако, вручную реализовать признак для типа объекта. Поскольку типы объектов несортированные, мы должны сначала позволить ParentTrait
быть реализованы для несортированных типов:
trait ParentTrait for Sized? {}
Тогда мы можем предоставить impl
из ParentTrait
для типа ChildTrait
объекта:
impl<'a> ParentTrait for ChildTrait+'a {}
Если мы попытаемся компилировать теперь мы получаем различные ошибки:
<anon>:9:40: 9:42 error: cannot move out of dereference of `&`-pointer
<anon>:9 let parents = children.iter().map(|&e| e as Box<ParentTrait>);
^~
<anon>:9:41: 9:42 note: attempting to move value to here
<anon>:9 let parents = children.iter().map(|&e| e as Box<ParentTrait>);
^
<anon>:9:41: 9:42 help: to prevent the move, use `ref e` or `ref mut e` to capture value by reference
<anon>:9 let parents = children.iter().map(|&e| e as Box<ParentTrait>);
мы можем использовать into_iter
вместо iter
потреблять первоначальный Vec
:
fn main() {
let mut children: Vec<Box<ChildTrait>> = vec![];
let parents = children.into_iter().map(|e| e as Box<ParentTrait>);
}
Но тогда мы получаем внутреннюю ошибку компилятора:
error: internal compiler error: trying to take the sizing type of ChildTrait, an unsized type
note: the compiler unexpectedly panicked. this is a bug.
note: we would appreciate a bug report: http://doc.rust-lang.org/complement-bugreport.html
note: run with `RUST_BACKTRACE=1` for a backtrace
task 'rustc' panicked at 'Box<Any>', /build/rust-git/src/rust/src/libsyntax/diagnostic.rs:175
Та же ошибка возникает также с этим кодом:
fn main() {
let mut children: Vec<Box<ChildTrait>> = vec![];
let parents = children.iter().map(|e| &**e as &ParentTrait);
}
На данный момент, Я не знаю, удастся ли после фиксации ICE успешно скомпилировать или нет.
Благодарим вас за разъяснение! Вы знаете, если это ошибка, которая уже известна? Else Я бы представил новый отчет об ошибках. – LinuCC
Подтверждено, что в настоящее время невозможно отличить черты таким образом, но должно появиться в будущем. – LinuCC