使用Option :: map to Box :: new特征对象不起作用

时间:2018-02-19 10:25:41

标签: rust

trait FooTrait {}

struct FooStruct;

impl FooTrait for FooStruct {}

fn main() {
    let maybe_struct: Option<FooStruct> = None;

//  Does not compile, "expected trait FooTrait, found struct `FooStruct`"
//  let maybe_trait: Option<Box<FooTrait>> = maybe_struct.map(Box::new);

    // Compiles fine
    let maybe_trait: Option<Box<FooTrait>> = match maybe_struct {
        Some(s) => Some(Box::new(s)),
        None => None,
    };
}

Rustc 1.23.0。为什么第一种方法没有编译?我错过了一些明显的东西,或者......嗯?

1 个答案:

答案 0 :(得分:5)

Box::new仅适用于大小不一的类型;也就是说,它采用大小为T的值并返回Box<T>。在某些地方,Box<T>可以coerced加入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)一样使用它。请参阅Playground