我尝试了以下代码:
fn main() {
let v2 = vec![1; 10];
println!("{}", v2);
}
但编译器抱怨:
error[E0277]: `std::vec::Vec<{integer}>` doesn't implement `std::fmt::Display`
--> src/main.rs:3:20
|
3 | println!("{}", v2);
| ^^ `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`
有没有人为Vec<T>
实现这个特性?
有没有人为
Vec<T>
实现这个特性?
没有。
令人惊讶的是,这是一个明确正确的答案;这是罕见的,因为证明没有东西通常很难或不可能。那么我们怎么能这么肯定呢?
Rust有一个非常严格的连贯规则,impl Trait for Struct
只能做:
Trait
在同一箱子里Struct
在同一个箱子里而在其他地方;让我们的try it:
impl<T> std::fmt::Display for Vec<T> {
fn fmt(&self, _: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
Ok(())
}
}
收益率:
error[E0210]: type parameter `T` must be used as the type parameter for some local type (e.g., `MyStruct<T>`)
--> src/main.rs:1:1
|
1 | impl<T> std::fmt::Display for Vec<T> {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type parameter `T` must be used as the type parameter for some local type
|
= note: only traits defined in the current crate can be implemented for a type parameter
此外,要使用特征,它需要在范围内(因此,您需要链接到其条件箱),这意味着:
Display
的箱子和Vec
的箱子都有联系Display
实施Vec
因此我们得出结论,没有人为Display
实施Vec
。
作为一种解决方法,如Manishearth所示,您可以使用Debug
特征,它可以通过"{:?}"
作为格式说明符调用。
let v2 = vec![1; 10];
println!("{:?}", v2);
{}
用于字符串和其他值,可以直接显示给用户。没有一种方法可以向用户显示矢量。
{:?}
格式化程序可用于调试它,它看起来像:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Display
是提供{}
背后方法的特征,Debug
是{:?}
如果您知道向量包含的元素的类型,则可以创建一个以向量作为参数的结构,并为该结构实现Display
。
use std::fmt::{Display, Formatter, Error};
struct NumVec(Vec<u32>);
impl Display for NumVec {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let mut comma_separated = String::new();
for num in &self.0[0..self.0.len() - 1] {
comma_separated.push_str(&num.to_string());
comma_separated.push_str(", ");
}
comma_separated.push_str(&self.0[self.0.len() - 1].to_string());
write!(f, "{}", comma_separated)
}
}
fn main() {
let numbers = NumVec(vec![1; 10]);
println!("{}", numbers);
}
这是一个单行,也应该适合你:
println!("[{}]", v2.iter().fold(String::new(), |acc, &num| acc + &num.to_string() + ", "));
Here是一个可运行的例子。
在我自己的情况下,我从函数调用接收到Vec<&str>
。我不想将函数签名更改为自定义类型(我可以为其实现Display
特性)。
对于我的一个案例,我能够将我的Vec
的显示变成一个单行,我直接用println!()
如下:
println!("{}", myStrVec.iter().fold(String::new(), |acc, &arg| acc + arg));
(lambda可以适用于不同的数据类型,或更简洁的Display
特性实现。)