Use Option :: map for Box :: new feature object not working

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. Why doesn't the first approach compile? Did I miss something obvious or ... yes?

+4
source share
1 answer

Box::newonly works with dimensions; that is, it takes a size value Tand returns Box<T>. In some places, a Box<T>may be forced to Box<U>(if T: Unsize<U>).

Such coercion does not occur in .map(Box::new), but in Some(Box::new(s)); the latter is basically the same as Some(Box::new(s) as Box<FooTrait>).

You could create (at night) your own box designer that returns fields of non-standard types such as this:

#![feature(unsize)]

fn box_new_unsized<T, U>(v: T) -> Box<U>
where
    T: ::std::marker::Unsize<U>,
    U: ?Sized,
{
    Box::<T>::new(v)
}

and use it like .map(box_new_unsized). See Playground .

+5
source

Source: https://habr.com/ru/post/1693822/


All Articles