如何打印 Vec?
How to print a Vec?
我尝试了以下代码:
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>
实现了这个特性吗?
let v2 = vec![1; 10];
println!("{:?}", v2);
{}
用于字符串和其他可以直接显示给用户的值。没有单一的方法可以向用户显示矢量。
{:?}
格式化程序可以用来调试它,它看起来像:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Display
是提供 {}
背后方法的特征,而 Debug
是 {:?}
Does anyone implement this trait for Vec<T>
?
没有
令人惊讶的是,这是一个明显正确的答案;这很少见,因为证明事物不存在通常是困难的或不可能的。那我们怎么能这么确定呢?
Rust有非常严格的一致性规则,impl Trait for Struct
只能做到:
- 与
Trait
在同一个 crate 中
- 或与
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
的箱子链接
- 都没有为
Vec
实施 Display
因此我们得出结论,没有人为 Vec
.
实施 Display
作为解决方法,如 Manishearth 所指出的,您可以使用 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
特征实现。)
有什么理由不把之前收藏的vector的内容逐项写出来吗w/o? *)
use std::fmt::{Display, Formatter, Error};
struct NumVec(Vec<u32>);
impl Display for NumVec {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let v = &self.0;
if v.len() == 0 {
return Ok(());
}
for num in &v[0..v.len() - 1] {
if let Err(e) = write!(f, "{}, ", &num.to_string()) {
return Err(e);
}
}
write!(f, "{}", &v[v.len() - 1])
}
}
fn main() {
let numbers = NumVec(vec![1; 10]);
println!("{}", numbers);
}
*) 没有。
因为我们要显示一些东西,所以 Display
特性是肯定实现的。所以这是正确的 Rust,因为:文档说 ToString trait:
"这个特性对于任何实现 Display
特性的类型都会自动实现。因此,ToString
不应该直接实现:Display
应该被实现,并且您可以免费获得 ToString
实施。"
特别是在 space 受限的微控制器上,我肯定会采用此解决方案并立即编写。
从 Rust 1.58 开始,有一种稍微更简洁的方式来打印矢量(或其他任何东西)。这使您可以将要打印的变量放在花括号内,而无需将其放在末尾。对于打印矢量所需的调试格式,您可以在大括号中添加 :?
,如下所示:
fn main() {
let v2 = vec![1; 10];
println!("{v2:?}");
}
我尝试了以下代码:
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>
实现了这个特性吗?
let v2 = vec![1; 10];
println!("{:?}", v2);
{}
用于字符串和其他可以直接显示给用户的值。没有单一的方法可以向用户显示矢量。
{:?}
格式化程序可以用来调试它,它看起来像:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Display
是提供 {}
背后方法的特征,而 Debug
是 {:?}
Does anyone implement this trait for
Vec<T>
?
没有
令人惊讶的是,这是一个明显正确的答案;这很少见,因为证明事物不存在通常是困难的或不可能的。那我们怎么能这么确定呢?
Rust有非常严格的一致性规则,impl Trait for Struct
只能做到:
- 与
Trait
在同一个 crate 中
- 或与
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
的箱子链接
- 都没有为
Vec
实施
Display
因此我们得出结论,没有人为 Vec
.
Display
作为解决方法,如 Manishearth 所指出的,您可以使用 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
特征实现。)
有什么理由不把之前收藏的vector的内容逐项写出来吗w/o? *)
use std::fmt::{Display, Formatter, Error};
struct NumVec(Vec<u32>);
impl Display for NumVec {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let v = &self.0;
if v.len() == 0 {
return Ok(());
}
for num in &v[0..v.len() - 1] {
if let Err(e) = write!(f, "{}, ", &num.to_string()) {
return Err(e);
}
}
write!(f, "{}", &v[v.len() - 1])
}
}
fn main() {
let numbers = NumVec(vec![1; 10]);
println!("{}", numbers);
}
*) 没有。
因为我们要显示一些东西,所以 Display
特性是肯定实现的。所以这是正确的 Rust,因为:文档说 ToString trait:
"这个特性对于任何实现 Display
特性的类型都会自动实现。因此,ToString
不应该直接实现:Display
应该被实现,并且您可以免费获得 ToString
实施。"
特别是在 space 受限的微控制器上,我肯定会采用此解决方案并立即编写。
从 Rust 1.58 开始,有一种稍微更简洁的方式来打印矢量(或其他任何东西)。这使您可以将要打印的变量放在花括号内,而无需将其放在末尾。对于打印矢量所需的调试格式,您可以在大括号中添加 :?
,如下所示:
fn main() {
let v2 = vec![1; 10];
println!("{v2:?}");
}