如何实现ToString特性来创建逗号分隔的字符串而不使用尾随逗号?

时间:2016-05-22 11:59:38

标签: rust

我有这段代码:

struct A {
    names: Vec<String>,
}

impl ToString for A {
    fn to_string(&self) -> String {
        // code here
    }
}

fn main() {
    let a = A {
        names: vec!["Victor".to_string(), "Paul".to_string()],
    };
    println!("A struct contains: [{}].", a.to_string());
}

预期产出:

  

结构包含:[Victor,Paul]。

实现此特性以实现目标的最佳方法是什么?我尝试了一些奇怪的'每个'和其他变种,但每个都给我一个这样的尾随逗号:

  

维克多,保罗,

当然我可以稍后把它弹出来,但我对这种语言很感兴趣,所以我想知道最好的做法。这只是我尝试过的一个例子,但没关系,我问的是如何最有效地做到这一点。

1 个答案:

答案 0 :(得分:18)

根据the ToString documentation

  

对于实现Display特征的任何类型,都会自动实现此特征。因此,ToString不应直接实施:而应实施Display,并免费获得ToString实施。

您可以像这样实施Display

use std::fmt;

impl fmt::Display for A {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        let mut str = "";
        for name in &self.names {
            fmt.write_str(str)?;
            fmt.write_str(name)?;
            str = ", ";
        }
        Ok(())
    }
}

您无需致电to_string(但您可以):

fn main() {
    let a = A {
        names: vec!["Victor".to_string(), "Paul".to_string()],
    };
    println!("A struct contains: [{}].", a);
}

请注意Display

的目的
  

DisplayDebug类似,但Display用于面向用户的输出,因此无法导出。

如果您的意图是调试,则可以派生Debug

#[derive(Debug)]
struct A {
    names: Vec<String>,
}

fn main() {
    let a = A { names: vec![
        "Victor".to_string(),
        "Paul".to_string(),
    ]};
    // {:?} is used for debug
    println!("{:?}", a);
}

输出:

A { names: ["Victor", "Paul"] }

Formatter结构提供了丰富的方法集合,因此您可以编写自己的Debug实现:

impl fmt::Debug for A {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("A")
           .field("names", &self.names)
           .finish()
    }
}