rust - 有没有更好的方法来为拥有 DIsplay 事物集合的结构实现 Display?

标签 rust

我不断发现自己在为包含实现 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/

相关文章:

post - 如何使用带有 hyper 的 multipart/form-data 发布图像?

recursion - 这种递归联接如何在Rust中工作

rust - Rust 中有没有类似于 Go 中的 bufio.Reader.ReadSlice 的东西?

types - Rust 中的 Some 和 Option 有什么区别?

data-structures - BitVec 错误地附加 0 而不是 1

rust - rust 中函数接受闭包作为参数或返回闭包的惯用方式是什么?

rust -::和 . 之间有什么区别?在使用rust ?

error-handling - 在将filter_map与易错的映射功能一起使用时,如何汇总错误的迭代器?

rust - 从 Cranelift 发出 ASM

rust - 将 `&str` 附加到 `String` 的最有效方法是什么?