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,
};
}
Run Code Online (Sandbox Code Playgroud)
Rustc 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)
}
Run Code Online (Sandbox Code Playgroud)
并使用它.map(box_new_unsized).参见游乐场.