我不断发现自己在为包含实现 Display
的某种类型的 Vec
的结构编写 Display
。例如:
use std::fmt::Display;
struct VarTerm {
pub coeffecient: usize,
pub var_name: String,
}
impl Display for VarTerm {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}{}", self.coeffecient, self.var_name)
}
}
struct Function {
pub terms: Vec<VarTerm>,
}
impl Display for Function {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let strings = self
.terms
.iter()
.map(|s| format!("{}", s))
.collect::<Vec<String>>()
.join(" + ");
write!(f, "{}", strings)
}
}
fn main() {
let my_function = Function {
terms: vec![
VarTerm {coeffecient: 2,var_name: "x".to_string(),},
VarTerm {coeffecient: 4,var_name: "y".to_string(),},
VarTerm {coeffecient: 5,var_name: "z".to_string(),},
],
};
println!("All that work to print something: {}", my_function)
}
在很多地方,这对我来说看起来又笨重又丑陋 - 来自高级语言,我从来不喜欢 .iter()/.collect()
三明治(我喜欢知道为什么需要它,但是当 90% 以上的时间我只是从 Vec
转到 Vec
时,这很烦人)。在这种情况下,它还因 format!()
调用而变得更加复杂,我发誓这一定是错误的方法。
我不确定其中有多少是 Rust 固有的,又有多少是我不知道正确的方法。我想尽可能接近这样的东西:
self.terms.map(toString).join("+ ")
,这正是我在 Scala 等中所期望的。
我距离那里有多近?一路走来,对于前面提到的 iter
/collect
夹层,有什么可以做的吗?
最佳答案
有一个令人毛骨悚然的巧合,就在 2 分钟前,我查看了 itertools
箱中的一些方法。这个怎么样:
https://docs.rs/itertools/latest/itertools/trait.Itertools.html#method.join
fn join(&mut self, sep: &str) -> String
where
Self::Item: Display
Combine all iterator elements into one String, separated by sep.
Use the Display implementation of each element.
use itertools::Itertools;
assert_eq!(["a", "b", "c"].iter().join(", "), "a, b, c");
assert_eq!([1, 2, 3].iter().join(", "), "1, 2, 3");
编辑:此外,每当您问自己是否有更好的方法来实现特定特征时,特别是当实现有点递归时,您应该看看是否有derive
该特征的宏。事实证明是有的,尽管在一个单独的箱子里:
https://jeltef.github.io/derive_more/derive_more/display.html
示例:
#[derive(Display)]
#[display(fmt = "({}, {})", x, y)]
struct Point2D {
x: i32,
y: i32,
}
关于rust - 有没有更好的方法来为拥有 DIsplay 事物集合的结构实现 Display?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75251994/