Rust 特征对象锈向量的错误类型推断
我无法理解以下错误:Rust 特征对象锈向量的错误类型推断,rust,trait-objects,Rust,Trait Objects,我无法理解以下错误: // 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!
// 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)],
};
}
错误发生在我试图创建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,
};
让a_vec:vec=vec![框:新(a)];
设c=c{
c:a_vec,
};
我做的另一个实验是将C.C的类型改为Box而不是Vec,然后不管我如何启动它,它都会编译
在我看来,这可能是Rust关于特征对象向量的类型推断中缺少的一些特性/缺陷?我还是个新手,所以对此有任何想法都非常感谢 这都是预期的行为。一个
框,只要编译器知道目标类型是Box
,它就会隐式发生。但是,刚写的时候,
let a_vec = vec![Box::new(a)];
编译器不知道向量的项类型,因此它从右侧的表达式推断,这意味着a_vec
以类型vec
结束
不存在从Vec
到Vec
的未调整大小的强制。将Box
转换为Box
仅仅意味着将指针转换为堆栈上的胖指针,这是一种廉价的操作。转换这些元素的向量是非常不同的–它需要重新分配整个向量并取消每个元素的大小,这是一个相当昂贵的操作,因此它永远不会隐式发生
在所有实际编译的版本中,向量从一开始就被创建为Vec
,因为您告诉编译器这是您想要的类型。另一个有效的变体是Vec![框::新(a)为33;]
。错误本身是由于细指针(盒装混凝土结构)和胖指针(盒装dyn特性)之间的差异造成的。一个可以转换为另一个(前提是结构实现了trait),但有时编译器需要一些轻推来执行转换。这是一个好问题,无论是类型推断中的缺陷还是某个更深层次原则的结果。这都是预期的行为-我不期望的部分是针对vec![Box::new(a)]
不起作用,但适用于vec![Box::new(a)as quot]
开始工作。as
看起来是多余的-它给了编译器哪些没有它就无法推断的新信息?@user4815162342从某种意义上说,它实际上给了编译器更少的信息。编译器试图根据右侧推断a_vec
的类型。如果右侧为vec![Box::new(a)]
,编译器可以推断出完整的类型,Vec
,因为这是表达式的类型。如果将添加为
,编译器将无法再推断完整的类型,而只能推断Vec
。初始化c
之后,编译器会进一步提示
实际上是Box
。谢谢。我试图理解为什么编译器会推断出let a_vec=vec的向量的完整类型![Box::new(a);/*在需要vec的地方使用_vec*/
,但不要在中让c=c{c:vec![Box::new(a)]}
。我预计如果前者由于类型不匹配而无法编译,后者也会如此。或者,换句话说,如果为编译OP的代码而更改了编译器,在某些情况下会导致问题吗?@user4815162342 inlet c=c{c:vec![Box::new(a)]
,没有可推断的类型。结构c
的c
字段的类型已经已知。
let a_vec = vec![Box::new(a)];