为什么使用 Option::map 到 Box::new 特征对象不起作用?
Why does using Option::map to Box::new a trait object not work?
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。为什么第一种方法不能编译?我是不是遗漏了一些明显的东西,或者……嗯?
Box::new
仅适用于大小类型;也就是说,它采用大小类型 T
和 returns Box<T>
的值。在某些地方 Box<T>
可以是 coerced into a Box<U>
(if T: Unsize<U>
).
这种强制转换不会发生在 .map(Box::new)
中,但会发生在 Some(Box::new(s))
中;后者与Some(Box::new(s) as Box<FooTrait>)
.
基本相同
您可以创建(每晚)您自己的盒子构造函数,returns 像这样的未调整大小的盒子:
#![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。
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。为什么第一种方法不能编译?我是不是遗漏了一些明显的东西,或者……嗯?
Box::new
仅适用于大小类型;也就是说,它采用大小类型 T
和 returns Box<T>
的值。在某些地方 Box<T>
可以是 coerced into a Box<U>
(if T: Unsize<U>
).
这种强制转换不会发生在 .map(Box::new)
中,但会发生在 Some(Box::new(s))
中;后者与Some(Box::new(s) as Box<FooTrait>)
.
您可以创建(每晚)您自己的盒子构造函数,returns 像这样的未调整大小的盒子:
#![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。