我总是发现自己为包含实现Display的某种类型的Vec的 struct 编写了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%以上的时间只是从VecVec的时候,这很恼人).在这种情况下,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

将所有迭代器元素合并为一个字符串,以Sep分隔.

使用每个元素的显示实现.

use itertools::Itertools;

assert_eq!(["a", "b", "c"].iter().join(", "), "a, b, c");
assert_eq!([1, 2, 3].iter().join(", "), "1, 2, 3");

编辑:此外,每当您问自己是否有更好的方法来实现特定的特征时,especially什么时候实现会有一些递归,您应该查看是否有针对该特征的derive宏.结果是有的,尽管放在一个单独的 crate 里:

https://jeltef.github.io/derive_more/derive_more/display.html

示例:

#[derive(Display)]
#[display(fmt = "({}, {})", x, y)]
struct Point2D {
    x: i32,
    y: i32,
}

Rust相关问答推荐

在Rust中创建可变片段的可变片段的最有效方法是什么?

Rust kill std::processs::child

如果A == B,则将Rc A下推到Rc B

如何仅使用http机箱发送http请求?

无法将记录器向下转换回原始 struct

类型批注需要静态生存期

如何向下转换到MyStruct并访问Arc Mutex MyStruct实现的方法?

可以为rust构建脚本编写单元测试吗?

我们能确定Rust会优化掉Clone()吗?如果它会立即掉落?

Rust 中的复合 `HashSet` 操作或如何在 Rust 中获得 `HashSet` 的显式差异/并集

将多维数组转换为切片

Rust中如何实现一个与Sized相反的负特性(Unsized)

max(ctz(x), ctz(y)) 有更快的算法吗?

使用 Rust 从 Raspberry Pi Pico 上的 SPI 读取值

如何递归传递闭包作为参数?

在线程中运行时,TCPListener(服务器)在 ip 列表中的服务器实例之前没有从客户端接受所有客户端的请求

提取 struct 生成宏中字段出现的索引

为什么这个闭包没有比 var 长寿?

如何在没有 `make_contiguous()` 的情况下对 VecDeque 进行排序或反转?

为什么 u64::trailing_zeros() 在无分支工作时生成分支程序集?