为什么使用 Option::映射到 Box::new 一个特征对象不起作用?


trait FooTrait {}
struct FooStruct;
impl FooTrait for FooStruct {}
fn main() {
let maybe_struct: Option<dyn FooStruct> = None;
//  Does not compile
let maybe_trait: Option<Box<dyn FooTrait>> = maybe_struct.map(Box::new);
// Compiles fine
let maybe_trait: Option<Box<dyn FooTrait>> = match maybe_struct {
Some(s) => Some(Box::new(s)),
None => None,
};
}
error[E0404]: expected trait, found struct `FooStruct`
--> src/main.rs:9:34
|
9 |     let maybe_struct: Option<dyn FooStruct> = None;
|                                  ^^^^^^^^^ not a trait

鲁斯克 1.23.0。为什么第一种方法不编译?我是否错过了一些明显的东西,或者...哼?

Box::new仅适用于大小类型;也就是说,它接受大小类型的值T并返回Box<T>。 在某些地方,Box<T>可以被胁迫进入Box<U>(如果T: Unsize<U>)。

这种胁迫不会发生在.map(Box::new),而是发生在Some(Box::new(s));后者基本上与Some(Box::new(s) as Box<FooTrait>)相同。

您可以创建(每晚)自己的框构造函数,该构造函数返回未调整大小类型的框,如下所示:

#![feature(unsize)]
fn box_new_unsized<T, U>(v: T) -> Box<U>
where
T: ::std::marker::Unsize<U>,
U: ?Sized,
{
Box::<T>::new(v)
}

并像.map(box_new_unsized)一样使用它. 见游乐场。

最新更新