为什么不Vec 实现显示特征?

问题描述 投票:1回答:1

学习语言令我感到惊讶我无法打印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来说,这将是一件非常简单的任务,不是吗?我将DisplayVec<T>特性用于任何可序列化(或可转换为T)的String。为什么我不能这样做,我可以有不同的解释吗?这是类型系统的限制吗?

types rust type-systems
1个回答
10
投票

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

原则上,没有什么能阻止在Display中为Vec实现collections::vec,其中任何一个都被定义(最有可能在this中)。但是,故意没有这样做。正如在thisDisplay 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
© www.soinside.com 2019 - 2024. All rights reserved.