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