How to print! Option <Box <struct>>?

I try to print Option<Box<MyStruct>>, but I get a compilation error when trying to implement Display for Option<Box<MyStruct>>.

use std::fmt;

fn main() {
    let maybe_my_struct: Option<Box<MyStruct>> = Some(Box::new(MyStruct{foo:42}));
    println!("{}", maybe_my_struct);
}

struct MyStruct {
    foo: i32,
}

impl fmt::Display for Option<Box<MyStruct>> {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Some(MyStruct) => write!(formatter, "{}", self.foo),
            None => write!(formatter, "No struct"),
        }
    }
}

The error I get is:

error: the impl does not reference any types defined in this crate; 
only traits defined in the current crate can be implemented for arbitrary types [E0117]

I tried to inherit the type Optionand used it instead Display for MyOption<Box<MyStruct>>, but it gives the same result. What am I doing wrong?

+4
source share
1 answer

As you can see, you cannot implement a trait that you are not writing for a type that you are not writing. This is part of what is known as “consistency” and exists to prevent really strange things like linking to a library, which leads to a change in the behavior of the unrelated parts of your program.

Option MyOption , , , . , , , .

, Option :

struct MyOption<T>(Option<T>);

MyOption , , . , Option, .

... , Debug .

fn main() {
    let maybe_my_struct: Option<Box<MyStruct>> = Some(Box::new(MyStruct{foo:42}));
    println!("{:?}", Some(maybe_my_struct));
}

#[derive(Debug)]
struct MyStruct {
    foo: i32,
}

, Option<Box<MyStruct>>, ( Path , ). :

use std::fmt;

fn main() {
    let maybe_my_struct: Option<Box<MyStruct>> = Some(Box::new(MyStruct{foo:42}));
    println!("{:?}", maybe_my_struct);

    // Instead of displaying directly, display via a custom marker.
    println!("{}", maybe_my_struct.display());
    println!("{}", None::<Box<MyStruct>>.display());
}

#[derive(Debug)]
struct MyStruct {
    foo: i32,
}

// This is the marker we'll use to define our custom Display impl.
struct MmsDisplay<'a>(&'a Option<Box<MyStruct>>);

// This trait lets us extend Option<Box<MyStruct>> with a new method.
trait CustomMmsDisplay {
    fn display<'a>(&'a self) -> MmsDisplay<'a>;
}

impl CustomMmsDisplay for Option<Box<MyStruct>> {
    fn display<'a>(&'a self) -> MmsDisplay<'a> {
        MmsDisplay(self)
    }
}

// And here the display logic.
impl<'a> fmt::Display for MmsDisplay<'a> {
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
        match *self.0 {
            Some(ref ms) => write!(formatter, "{}", ms.foo),
            None => write!(formatter, "No struct"),
        }
    }
}
+6

All Articles