铁锈矢量的特征:铸造每个特征

时间:2014-11-22 03:43:05

标签: vector casting rust traits

我在将特征向量投射到不同特征的向量中时遇到了问题。

使用Type-casting arrays/vectors in Rust的方法,我基本上尝试了以下内容:

trait ParentTrait {}

trait ChildTrait: ParentTrait {}

fn main() {
    let mut children: Vec<Box<ChildTrait>> = vec![];
    let parents = children.iter().map(|&e| e as Box<ParentTrait>);
}

现在这不会编译,导致

error: the trait `core::kinds::Sized` is not implemented for the type `ChildTrait`
[...]
error: the trait `ParentTrait` is not implemented for the type `ChildTrait`
[...]

(第二个错误行是编译器的错误行为,我猜?)

我尝试了各种其他类型的References / Boxes并且无法使它工作。

我在这做错了什么, 这是否是更新版本的锈(0.13)的正确方法?

1 个答案:

答案 0 :(得分:1)

特质对象是非常奇怪的野兽。

什么是Box<ChildTrait>Box<T>实际上是*mut T的包装器。因此,Box<ChildTrait>包裹*mut ChildTrait。由于ChildTrait为特征命名,ChildTraitobject type。指向对象类型的指针由一对指针表示:指向该特征的vtable的指针,仅指向该特征,以及指向实际值的指针。

当我们从另一个特征继承特征时,这并不意味着我们可以从指向第二特征的vtable的指针获得指向第一特征的vtable的指针。这就是编译器抱怨

的原因
the trait `ParentTrait` is not implemented for the type `ChildTrait`

但是,我们可以手动为对象类型实现特征。由于对象类型是未分级的,因此我们必须首先允许{1}}实现未分类的类型:

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

此时,我不知道在修复ICE之后,这是否会成功编译。