gpt4 book ai didi

rust - 如何在类型已经实现 Display 的特征对象上实现 Display

转载 作者:行者123 更新时间:2023-11-29 08:29:10 28 4
gpt4 key购买 nike

我有一些代码返回 MyTrait 类型的特征对象,这样它就可以返回几个不同结构之一。我想为 trait 对象实现 Display trait,这样我就可以打印对象,并将详细信息委托(delegate)给各种结构,因为它们每个都需要自己的自定义格式化程序。

我可以通过将格式化方法作为 MyTrait 定义的一部分,然后为 MyTrait 实现 Display 和委派来实现这一点 - 比如这个:

trait MyTrait {
fn is_even(&self) -> bool;
fn my_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;
}

impl fmt::Display for MyTrait {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.my_fmt(f)
}
}

但是,我已经为每个实现 MyTrait 的结构实现了 Display 特性。这意味着我最终为每个结构提供了两种方法,它们做同样的事情 - fmt() 方法直接在结构上满足 Display 特征,以及 my_fmt() 上面代码调用的方法。这看起来笨拙且重复。有更简单的方法吗?

这里有一个完整的示例程序来说明这一点。它比我希望的要长一点(它基于我对上一个问题 Calling functions which return different types with shared trait and pass to other functions 的回答),但我想不出更简单的方法来说明这一点。当然,在这个玩具示例中,结构和 fmt 函数非常简单;在我的实际应用中,它们更复杂。

use std::fmt;

trait MyTrait {
fn is_even(&self) -> bool;
fn my_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result;
}

struct First {
v: u8,
}

struct Second {
v: Vec<u8>,
}

impl MyTrait for First {
fn is_even(&self) -> bool {
self.v % 2 == 0
}

fn my_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.v)
}
}

impl MyTrait for Second {
fn is_even(&self) -> bool {
self.v[0] % 2 == 0
}

fn my_fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.v[0])
}
}

fn make1() -> First {
First { v: 5 }
}

fn make2() -> Second {
Second { v: vec![2, 3, 5] }
}

// Implement Display for the structs and for MyTrait
impl fmt::Display for First {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.v)
}
}

impl fmt::Display for Second {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.v[0])
}
}

impl fmt::Display for MyTrait {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.my_fmt(f)
}
}

fn requires_mytrait<T: MyTrait + ?Sized>(v: &&T) {
println!("{:?}", v.is_even());
}

fn main() {
for i in 0..2 {
let v1;
let v2;
let v = match i {
0 => {
v1 = make1();
println!("> {}", v1); // Demonstrate that Display
// is implemented directly
// on the type.
&v1 as &MyTrait
}
_ => {
v2 = make2();
println!("> {}", v2); // Demonstrate that Display
// is implemented directly
// on the type.
&v2 as &MyTrait
}
};
requires_mytrait(&v);
println!("{}", v); // Here I print the trait object
}
}

谁能建议一种更简单、更简洁的方法来做到这一点?

最佳答案

您可以使 Display 成为 MyTrait 的 super 特征。

trait MyTrait: fmt::Display {
fn is_even(&self) -> bool;
}

这将使 MyTrait 的特征对象成为 Display。这仅在您希望 MyTrait 的所有实现者都实现 Display 时才有效,但在您之前的解决方案中也是如此。

关于rust - 如何在类型已经实现 Display 的特征对象上实现 Display,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54488320/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com