Как реализовать признак ToString для создания строки с разделителями-запятыми без конечной запятой?

У меня есть этот код:

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 ответов


по данным на ToString документация:

эта черта автоматически реализуется для любого типа, который реализует 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:

Display похож на Debug, а Display предназначен для вывода пользователя и поэтому не может быть получен.

если ваше намерение-debug, вы можете получить 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()
    }
}