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

时间:2015-11-17 14:11:35

标签: types rust type-systems

学习语言令我感到惊讶我无法打印Vec的实例:

fn main() {
    let v1 = vec![1, 2, 3];
    println!("{}", v1);
}
error[E0277]: `std::vec::Vec<{integer}>` doesn't implement `std::fmt::Display`
 --> src/main.rs:3:20
  |
3 |     println!("{}", v1);
  |                    ^^ `std::vec::Vec<{integer}>` cannot be formatted with the default formatter
  |
  = help: the trait `std::fmt::Display` is not implemented for `std::vec::Vec<{integer}>`
  = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
  = note: required by `std::fmt::Display::fmt`

我可以理解这一点,并且我知道如here所述使用{:?}调试占位符。不幸的是,我还没有理解答案,告诉我为什么不能这样做。无论是C#还是Haskell都不是一件轻而易举的事,不是吗?对于可序列化(或可转换为Display)的任何Vec<T>,我T实施String个特征。我可以对我为什么不这样做有不同的解释吗?这是类型系统的限制吗?

1 个答案:

答案 0 :(得分:11)

首先,你不能为外来类型实现外国特征,这就是ker所提供的link的问题和答案。

原则上,没有什么可以阻止在Display中为Vec实施collections::vec,而模块中定义了其中任何一个(最有可能是Display)。但是,故意没有这样做。正如thisthis RFC中所述,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)); } 特征旨在生成应向用户显示的字符串。但是,没有自然的方法从矢量生成这样的字符串。您想要以逗号分隔的项目还是以制表符分隔的项目?它们应该用括号或花括号包裹还是什么都没有?也许你想在单独的行上打印每个元素?没有一种方法。

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

Returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0. Returned values are chosen pseudorandomly with (approximately) uniform distribution from that range.