学习语言令我感到惊讶我无法打印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
个特征。我可以对我为什么不这样做有不同的解释吗?这是类型系统的限制吗?
答案 0 :(得分:11)
首先,你不能为外来类型实现外国特征,这就是ker所提供的link的问题和答案。
原则上,没有什么可以阻止在Display
中为Vec
实施collections::vec
,而模块中定义了其中任何一个(最有可能是Display
)。但是,故意没有这样做。正如this和this 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.