首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何打印!Option<Box<struct>>?

如何打印!Option<Box<struct>>?
EN

Stack Overflow用户
提问于 2015-05-31 05:33:38
回答 1查看 6.7K关注 0票数 7

我试图打印一个Option<Box<MyStruct>>,但是当我试图实现Display for Option<Box<MyStruct>>时,我会得到一个编译错误。

代码语言:javascript
运行
复制
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"),
        }
    }
}

我得到的错误是:

代码语言:javascript
运行
复制
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]

我尝试过对Option类型进行混叠,而不是实现Display for MyOption<Box<MyStruct>>,但结果是相同的。我做错了什么?

EN

Stack Overflow用户

回答已采纳

发布于 2015-05-31 05:39:18

正如你所看到的,你不能为你没有写的类型实现一个你没有写的特征。这是所谓的“一致性”的一部分,它的存在是为了防止真正奇怪的事情,如与库的链接,突然导致程序中不相关的部分改变行为。

Option别名为MyOption也不起作用,因为正如您所说的,它是一个别名。也就是说,它只是同一事物的另一个名称,它不是一种实际的,不同的类型。

现在,如果您围绕Option编写一个包装器,如下所示:

代码语言:javascript
运行
复制
struct MyOption<T>(Option<T>);

然后,MyOption将是一个新的、独特的类型,您可以为它实现一个特性。当然,您需要编写方法来包装和解压缩正在存储的实际Option

..。但是这一切都是无关紧要的,因为您也可以为您的结构派生Debug并使用它。

代码语言:javascript
运行
复制
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在标准库中使用了相同的方法)。就像这样:

代码语言:javascript
运行
复制
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"),
        }
    }
}
票数 9
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30554203

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档