rust - seguidores - Cómo imprimir un Vec?
hashtags para tener 100 likes en instagram (4)
Probé el siguiente código:
let v2 = vec![1; 10];
println!("{}", v2);
Pero el compilador se queja de que:
error[E0277]: the trait bound `std::vec::Vec<{integer}>: std::fmt::Display` is not satisfied
--> src/main.rs:3:20
|
3 | println!("{}", v2);
| ^^ trait `std::vec::Vec<{integer}>: std::fmt::Display` not satisfied
|
= note: `std::vec::Vec<{integer}>` cannot be formatted with the default formatter; try using `:?` instead if you are using a format string
= note: required by `std::fmt::Display::fmt`
¿Alguien implementa este rasgo para Vec<T>
?
¿Alguien implementa este rasgo para
Vec<>
?
No.
Y sorprendentemente, esta es una respuesta demostrablemente correcta; lo cual es raro ya que probar la ausencia de cosas suele ser difícil o imposible. Entonces, ¿cómo podemos estar tan seguros?
Rust tiene reglas de coherencia muy estrictas, el impl Trait for Struct
solo puede hacerse:
- ya sea en la misma caja como
Trait
- o en la misma caja como
Struct
y en ninguna otra parte; probemos:
impl<T> std::fmt::Display for Vec<T> {
fn fmt(&self, _: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
Ok(())
}
}
rendimientos:
error[E0210]: type parameter `T` must be used as the type parameter for some
local type (e.g. `MyStruct<T>`); only traits defined in the
current crate can be implemented for a type parameter
--> src/main.rs:1:1
|
1 | impl<T> std::fmt::Display for Vec<T> {
| ^
Además, para usar un trait
, debe estar dentro del alcance (y, por lo tanto, debe estar vinculado a su caja), lo que significa que:
- estás vinculado tanto con la caja de la
Display
como con la caja deVec
- ni implementar
Display
paraVec
y por lo tanto nos lleva a concluir que nadie implementa Display
for Vec
.
Como solución temporal, como lo indica Manishearth, puede usar el rasgo Debug
, que es invocable a través de "{:?}"
Como especificador de formato.
Aquí hay una línea que también debería funcionar para usted:
println!("[{}]", v2.iter().fold(String::new(), |acc, &num| acc + &num.to_string() + ", "));
Here hay un ejemplo ejecutable.
En mi propio caso, estaba recibiendo un Vec<&str>
de una llamada de función. No quería cambiar la firma de la función a un tipo personalizado (para el que podría implementar el rasgo de Display
).
Para mi caso único, pude convertir la pantalla de mi Vec
en una línea que utilicé con println!()
Directamente de la siguiente manera:
println!("{}", myStrVec.iter().fold(String::new(), |acc, &arg| acc + arg));
(La lambda se puede adaptar para su uso con diferentes tipos de datos, o para implementaciones de rasgos de Display
más concisas).
Si conoce el tipo de los elementos que contiene el vector, podría crear una estructura que tome vector como argumento e implementar la Display
para esa estructura.
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);
}
let v2 = vec![1; 10];
println!("{:?}", v2);
{}
es para cadenas y otros valores que se pueden mostrar directamente al usuario. No hay una sola forma de mostrar un vector a un usuario, sin embargo, {:?}
Se puede usar para depurarlo, y se verá así:
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
Display
es el rasgo que proporciona el método detrás de {}
, y la Debug
es para {:?}