如何解决特征对象的 Rust 向量类型推断不正确
我无法理解以下错误:
// test.rs
struct A {
a: u32
}
trait B { }
impl B for A { }
struct C {
c: Vec<Box<dyn B>>,}
fn test() {
let a = A {a: 1};
let a_vec = vec![Box::new(a)];
let c = C {
c: a_vec,// c: vec![Box::new(a)],};
}
编译错误:
mismatched types
expected trait object `dyn test::B`,found struct `test::A`
错误发生在我尝试创建 C 的那一行。有趣的是,如果我按照以下方式创建 C,那么它编译没问题。
let c = C {
c: vec![Box::new(a)],};
另一种可行的方法是
let a_vec: Vec<Box<dyn B>> = vec![Box::new(a)];
let c = C {
c: a_vec,};
我做的另一个实验是将 C.c 的类型改为 Box 而不是 Vec
在我看来,这可能是 Rust 关于特征对象向量的类型推断的一些缺失功能/错误?我对 Rust 还是很陌生,因此非常感谢您对此的任何想法!
解决方法
这都是预期的行为。可以将 Box<A>
强制转换为 Box<dyn B>
– 这称为 unsized coercion,只要编译器知道目标类型是 Box<dyn B>
,它就会隐式发生。然而,当刚写作时
let a_vec = vec![Box::new(a)];
编译器不知道向量的项类型,因此它从右侧的表达式推断它,这意味着 a_vec
以类型 Vec<Box<A>>
结尾。>
从 Vec<Box<A>>
到 Vec<Box<dyn B>>
没有无大小的强制转换。将 Box<A>
转换为 Box<dyn B>
只是意味着将指针转换为堆栈上的胖指针,这是一种廉价的操作。转换这些元素的向量是非常不同的——它需要重新分配整个向量并调整每个元素的大小,这是一个相当昂贵的操作,所以它永远不应该隐式发生。
在实际编译的所有版本中,向量从一开始就创建为 Vec<Box<dyn B>>
,因为您告诉编译器这是您想要的类型。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。