为什么Vec <T>没有实现显示特征?

Use*_*rol 2 types type-systems rust

学习语言让我感到惊讶我无法输出以下实例Vec:

fn main() {
    let v1 = vec![1, 2, 3];
    println!("{}", v1);
}
Run Code Online (Sandbox Code Playgroud)

我能理解这一点,我知道使用的{:?}调试占位符描述这里.不幸的是,我还不明白答案,告诉我为什么不能这样做.对于C#或Haskell来说,这将是一件非常简单的任务,不是吗?我将为任何可序列化(或可转换为)的Display特性实现特征.为什么我不能这样做,我可以有不同的解释吗?这是类型系统的限制吗?Vec<T>TString

Vla*_*eev 10

首先,你不能为外来类型实现外来特征,这就是ker提供的链接的问题和答案.

原则上,没有什么能够阻止实现DisplayVec其中定义它们中的一个模块(最有可能在collections::vec).但是,故意没有这样做.如 RFC所述,该Display特征旨在产生应向用户显示的字符串.但是,没有自然的方法从矢量生成这样的字符串.您想要以逗号分隔的项目还是以制表符分隔的项目?它们应该用括号或花括号包裹还是什么都没有?也许你想在单独的行上打印每个元素?没有一种方法.

解决这个问题的最简单方法是使用newtype包装器.例如:

use std::fmt;

struct SliceDisplay<'a, T: 'a>(&'a [T]);

impl<'a, T: fmt::Display + 'a> fmt::Display for SliceDisplay<'a, T> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let mut first = true;
        for item in self.0 {
            if !first {
                write!(f, ", {}", item)?;
            } else {
                write!(f, "{}", item)?;
            }
            first = false;
        }
        Ok(())
    }
}

fn main() {
    let items = vec![1, 2, 3, 4];
    println!("{}", SliceDisplay(&items));
}
Run Code Online (Sandbox Code Playgroud)

  • 使用 itertools 有一个很好的快捷方式: println!("{}", items.iter().format(", ")); (2认同)