【问题标题】:How to implement the ToString trait to create a comma-delimited string without a trailing comma?如何实现 ToString 特征以创建没有尾随逗号的逗号分隔字符串?
【发布时间】:2016-05-22 11:59:38
【问题描述】:

我有这个代码:

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]。

实现此特征以实现目标的最佳方法是什么?我尝试了一些奇怪的 'for each' 和其他变体,但每个变体都给我一个尾随逗号,如下所示:

维克多,保罗,

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

【问题讨论】:

    标签: rust


    【解决方案1】:

    根据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()
        }
    }
    

    【讨论】:

    • 一切看起来都很棒,但我应该关心fmt.write_str() 返回值吗?编译器抱怨必须使用结果并给出警告。
    • 你是对的。调用必须由try! 宏包裹。我更新了答案。谢谢。
    • 你如何看待与stackoverflow.com/q/22243527/155423 重复关闭?
    • @Shepmaster 我认为这个问题不是重复的。这个问题是关于实现ToString,虽然最终可能意味着实现Display,但关注点与实现Debug不同。
    • 请有人指出一个资源,它阐明了自动为Display 启用ToString 的底层魔法吗? Display trait 文档本身并没有提到这种“免费”实现,而 ToString 有。这似乎违反直觉
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    • 2010-09-17
    相关资源
    最近更新 更多