Rust 防锈打印选项自定义结构

Rust 防锈打印选项自定义结构,rust,Rust,在rust中,我希望在我的impl fmt::Display for MainStruct中能够打印另一个结构 #[derive(Clone, Default)] pub struct MainStruct { pub child: Option<ChildStruct> } #[derive(Clone, Default)] pub struct ChildStruct { pub field: String } impl std::fmt::Display fo

在rust中,我希望在我的
impl fmt::Display for MainStruct
中能够打印另一个结构

#[derive(Clone, Default)]
pub struct MainStruct {
    pub child: Option<ChildStruct>
}
#[derive(Clone, Default)]
pub struct ChildStruct {
    pub field: String
}

impl std::fmt::Display for MainStruct {
   fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
       write!(f, "MainStruct: child:{}", self.child)
   }
}
impl std::fmt::Display for ChildStruct {
   fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
       write!(f, "ChildStruct: field:{}", self.field)
   }
}
#[派生(克隆,默认)]
pub结构主体结构{
pub-child:选项
}
#[派生(克隆,默认)]
pub结构ChildStruct{
发布字段:字符串
}
impl std::fmt::主结构的显示{
fn fmt(&self,f:&mut std::fmt::Formatter)->std::fmt::Result{
写!(f,“主体结构:子:{}”,self.child)
}
}
impl std::fmt::ChildStruct的显示{
fn fmt(&self,f:&mut std::fmt::Formatter)->std::fmt::Result{
写!(f,“ChildStruct:field:{}”,self.field)
}
}

我试过使用默认的
{}
格式化程序和
{:?}
格式化程序,但没有成功。

问题是
选项
没有实现
显示
特性。因此,您必须从选项中获取值。最简单的方法是
.unwrap()
。但是,如果选项为“无”,则会出现恐慌。(其他解包方法有
expect
match
,…)

如果使用
.unwrap()
该值将移出该选项。因此,该选项现在将无效,因为它不再包含任何内容。编译器会通过一个错误来防止这种情况发生
无法移出“self.child”

因此,您实际需要的是一个不使用子对象的引用。因此,您需要从选项中选择
&T
&mut T
。您可以使用
.as_ref()
选项
转换为
选项
。然后,如果您执行
.unwrap()
操作,编译器将不再抱怨,因为您只需复制
&T
指针

因此,如果更改以下内容,代码将编译:

impl std::fmt::主结构显示{
fn fmt(&self,f:&mut std::fmt::Formatter)->std::fmt::Result{
写!(f,“主结构:子:{}”,self.child.as_ref().unwrap())
}
}

问题在于
选项
没有实现
显示
特性。因此,您必须从选项中获取值。最简单的方法是
.unwrap()
。但是,如果选项为“无”,则会出现恐慌。(其他解包方法有
expect
match
,…)

如果使用
.unwrap()
该值将移出该选项。因此,该选项现在将无效,因为它不再包含任何内容。编译器会通过一个错误来防止这种情况发生
无法移出“self.child”

因此,您实际需要的是一个不使用子对象的引用。因此,您需要从选项中选择
&T
&mut T
。您可以使用
.as_ref()
选项
转换为
选项
。然后,如果您执行
.unwrap()
操作,编译器将不再抱怨,因为您只需复制
&T
指针

因此,如果更改以下内容,代码将编译:

impl std::fmt::主结构显示{
fn fmt(&self,f:&mut std::fmt::Formatter)->std::fmt::Result{
写!(f,“主结构:子:{}”,self.child.as_ref().unwrap())
}
}

由于
选项
没有实现
显示
,您必须自己编写一些逻辑来处理两种可能的情况。最简单的方法可能是直接匹配
选项

impl std::fmt::Display for MainStruct {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "MainStruct: child: ")?;
        match self.child.as_ref() {
            Some(child) => write!(f, "Some({})", child),
            None => write!(f, "None"),
        }
    }
}

下面是一个简短的测试用例。

由于
选项
没有实现
显示
,您必须自己编写一些逻辑来处理两种可能的情况。最简单的方法可能是直接匹配
选项

impl std::fmt::Display for MainStruct {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "MainStruct: child: ")?;
        match self.child.as_ref() {
            Some(child) => write!(f, "Some({})", child),
            None => write!(f, "None"),
        }
    }
}

下面是一个简短的测试用例。

子项
Some()
None
时,您可以分别说明您想要显示什么吗?听起来您是在尝试实现
调试
而不是
显示
<无论
t
实现了什么,都没有为
选项实现code>Display
,这是故意的。你能说明一下当
子项
Some(u)
None
时,你想分别显示什么吗?听起来你想实现
Debug
,而不是
Display
<无论
t
实现什么,都不会为
选项实现code>Display
,这是故意的。请注意,如果
self.child
None
,则
展开
会导致恐慌。有什么解决方案可以防止这种情况发生吗?检查
if self.child.is_some()
if!self.child.is_none()
?你说得对。我调整了解决方案,希望现在一切正常。请注意,如果
self.child
None
,则
unwrap
会导致恐慌。有什么解决方案可以防止这种情况发生吗?检查
if self.child.is_some()
if!self.child.is_none()
?你说得对。我调整了解决方案,希望现在一切正常。