7
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

Rustc 1.23.0。为什么第一种方法不能编译?我是否遗漏了一些明显的东西,或者......嗯?

4

1 回答 1

7

Box::new仅适用于大小类型;也就是说,它接受一个大小类型的值T并返回Box<T>。在某些地方,aBox<T>可以被强制转换为Box<U>(if 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). 见游乐场

于 2018-02-19T10:44:07.687 回答