Как вы можете видеть, вы не можете реализовать черту, которую вы не пишете, для типа, который вы не пишете. Это часть того, что известно как «согласованность» и существует для предотвращения действительно странных вещей, таких как привязка к библиотеке, что приводит к тому, что несвязанные части вашей программы меняют поведение.
Aliasing 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's 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"),
}
}
}