简体   繁体   English

特征 object 的 Rust 向量的类型推断不正确

[英]Incorrect type inference for Rust vector of trait object

I am having trouble understanding the following error:我无法理解以下错误:

// 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)],
    };
}

Compile error:编译错误:

mismatched types

expected trait object `dyn test::B`, found struct `test::A`

The error occurs on the line where I try to create C.错误发生在我尝试创建 C 的行上。 What's interesting is that if I create C in the following way then it compiles alright.有趣的是,如果我按照以下方式创建 C ,那么它可以编译。

let c = C {
        c: vec![Box::new(a)],
    };

Another way that would work is另一种可行的方法是

let a_vec: Vec<Box<dyn B>> = vec![Box::new(a)];
let c = C {
        c: a_vec,
    };

One other experiment I did is to change the type of C.c to just Box instead of Vec<Box>, and then it compiles no matter how I initiate it.我做的另一个实验是将 C.c 的类型更改为 Box 而不是 Vec<Box>,然后无论我如何启动它都会编译。

Seems to me this might be some missing feature/bug of Rust's type inference regarding vector of trait objects?在我看来,这可能是 Rust 关于特征对象向量的类型推断的一些缺失功能/错误? I am still very new to Rust so any idea on this is really appreciated!我对 Rust 还是很陌生,所以对此的任何想法都非常感谢!

This is all expected behaviour.这都是预期的行为。 A Box<A> can be coerced into a Box<dyn B> – this is called an unsized coercion , and it happens implicitly whenever the compiler knows that the target type is Box<dyn B> .可以将Box<A>强制转换为Box<dyn B> ——这称为未调整大小的强制转换,只要编译器知道目标类型是Box<dyn B> ,它就会隐式发生。 However, when just writing但是,刚写的时候

let a_vec = vec![Box::new(a)];

the compiler doesn't know the item type of the vector, so it infers it from the expression on the right-hand side, meaning that a_vec ends up with the type Vec<Box<A>> .编译器不知道向量的项目类型,因此它从右侧的表达式推断它,这意味着a_vecVec<Box<A>>类型结束。

There is no unsized coercion from Vec<Box<A>> to Vec<Box<dyn B>> .Vec<Box<A>>Vec<Box<dyn B>>没有大小不一的强制。 Converting Box<A> to Box<dyn B> simply means converting a pointer to a fat pointer on the stack, which is a cheap operation.Box<A>转换为Box<dyn B>仅意味着将指针转换为堆栈上的胖指针,这是一种廉价的操作。 Converting vectors of these elements is very different – it would require reallocating the whole vector and unsizing each element, which is a rather expensive operation, so it should never happen implicitly.转换这些元素的向量是非常不同的——它需要重新分配整个向量并取消每个元素的大小,这是一个相当昂贵的操作,所以它不应该隐式发生。

In all the versions that actually compile, the vector is created as a Vec<Box<dyn B>> right from the get-go, since you tell the compiler that's the type you want.在所有实际编译的版本中,向量从一开始就被创建为Vec<Box<dyn B>> ,因为您告诉编译器这是您想要的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM