Implementiert jemand dieses Merkmal für Vec<T>
?
Nein.
Und überraschenderweise ist dies eine nachweislich richtige Antwort. Das ist selten, da es normalerweise schwierig oder unmöglich ist, das Fehlen von Dingen zu beweisen. Wie können wir also so sicher sein?
Rust hat sehr strenge Kohärenzregeln, die impl Trait for Struct
nur gemacht werden können:
- entweder in der gleichen Kiste wie
Trait
- oder in der gleichen Kiste wie
Struct
und nirgendwo anders; Lass es uns versuchen :
impl<T> std::fmt::Display for Vec<T> {
fn fmt(&self, _: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
Ok(())
}
}
Ausbeuten:
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
Um ein Merkmal zu verwenden, muss es außerdem im Geltungsbereich sein (und daher müssen Sie mit seiner Kiste verknüpft sein). Dies bedeutet, dass:
- Sie sind sowohl mit der Kiste
Display
als auch mit der Kiste von verbundenVec
- weder implementieren
Display
fürVec
und führt uns daher zu dem Schluss, dass niemand Display
für implementiert Vec
.
Um dies zu umgehen, können Sie, wie von Manishearth angegeben, das Debug
Merkmal verwenden, das über "{:?}"
als Formatbezeichner aufgerufen werden kann.
struct Mine(That3rdPartyType);
und dannimpl Display for Mine
.let v2 = vec![1; 10]; println!("{:?}", v2);
{}
ist für Zeichenfolgen und andere Werte, die dem Benutzer direkt angezeigt werden können. Es gibt keine einzige Möglichkeit, einem Benutzer einen Vektor anzuzeigen.Der
{:?}
Formatierer kann zum Debuggen verwendet werden und sieht folgendermaßen aus:Display
ist das Merkmal, das die Methode dahinter liefert{}
, undDebug
für ist{:?}
quelle
Wenn Sie den Typ der Elemente kennen, die der Vektor enthält, können Sie eine Struktur erstellen, die den Vektor als Argument verwendet, und
Display
diese Struktur implementieren .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); }
quelle
Display
.Hier ist ein Einzeiler, der auch für Sie funktionieren sollte:
println!("[{}]", v2.iter().fold(String::new(), |acc, &num| acc + &num.to_string() + ", "));
Hier ist ein lauffähiges Beispiel.
In meinem Fall erhielt ich einen
Vec<&str>
von einem Funktionsaufruf. Ich wollte die Funktionssignatur nicht in einen benutzerdefinierten Typ ändern (für den ich dasDisplay
Merkmal implementieren konnte ).Für meinen Einzelfall konnte ich das Display meines
Vec
in einen Einzeiler verwandeln, den ichprintln!()
direkt wie folgt verwendete:println!("{}", myStrVec.iter().fold(String::new(), |acc, &arg| acc + arg));
(Das Lambda kann für die Verwendung mit verschiedenen Datentypen oder für
Display
präzisere Implementierungen von Merkmalen angepasst werden .)quelle
Does anyone implement this trait for Vec<T>?
Ja, so habe ich es gemacht
fn main() { let a = vec![10,12,13]; println!("{:?}",display(a)); } use std::fmt::Debug; fn display<T: Debug>(a: Vec<T>) -> Vec<T> { let mut new_vec : Vec<T> = Vec::new(); for i in a { new_vec.push(i); } return new_vec }
quelle