Antworten:
Wenn Sie Zeichenfolgen verketten, müssen Sie Speicher zuweisen, um das Ergebnis zu speichern. Am einfachsten ist String
und &str
:
fn main() {
let mut owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
owned_string.push_str(borrowed_string);
println!("{}", owned_string);
}
Hier haben wir eine eigene Zeichenfolge, die wir mutieren können. Dies ist effizient, da wir möglicherweise die Speicherzuordnung wiederverwenden können. Es gibt einen ähnlichen Fall für String
und String
, wie &String
dereferenziert werden kann als&str
.
fn main() {
let mut owned_string: String = "hello ".to_owned();
let another_owned_string: String = "world".to_owned();
owned_string.push_str(&another_owned_string);
println!("{}", owned_string);
}
Danach another_owned_string
bleibt unberührt (kein mut
Qualifier beachten ). Es gibt eine weitere Variante , die verbraucht die String
aber nicht erfordert es wandelbar zu sein. Dies ist eine Implementierung des Add
Merkmals , das a String
als linke Seite und a &str
als rechte Seite nimmt:
fn main() {
let owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
let new_owned_string = owned_string + borrowed_string;
println!("{}", new_owned_string);
}
Beachten Sie, dass owned_string
nach dem Anruf an nicht mehr darauf zugegriffen werden kann +
.
Was wäre, wenn wir eine neue Saite produzieren wollten, die beide unberührt ließ? Der einfachste Weg ist zu verwenden format!
:
fn main() {
let borrowed_string: &str = "hello ";
let another_borrowed_string: &str = "world";
let together = format!("{}{}", borrowed_string, another_borrowed_string);
println!("{}", together);
}
Beachten Sie, dass beide Eingabevariablen unveränderlich sind, sodass wir wissen, dass sie nicht berührt werden. Wenn wir das Gleiche für eine beliebige Kombination von tun wolltenString
, können wir die Tatsache nutzen, dass String
auch formatiert werden kann:
fn main() {
let owned_string: String = "hello ".to_owned();
let another_owned_string: String = "world".to_owned();
let together = format!("{}{}", owned_string, another_owned_string);
println!("{}", together);
}
Sie müssen nicht haben zu verwenden ,format!
, though. Sie können eine Zeichenfolge klonen und die andere Zeichenfolge an die neue Zeichenfolge anhängen:
fn main() {
let owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
let together = owned_string.clone() + borrowed_string;
println!("{}", together);
}
Hinweis - Alle von mir erstellten Typspezifikationen sind redundant. Der Compiler kann auf alle hier verwendeten Typen schließen. Ich habe sie einfach hinzugefügt, um Leuten, die neu bei Rust sind, klar zu sein, da ich erwarte, dass diese Frage bei dieser Gruppe beliebt ist!
Add
/ +
symbol? Sie könnten es abdecken, wenn Sie wollen.
.to_owned()
und .to_string()
seit dem obigen Kommentar dank impl Spezialisierung behoben wurde. Beide haben jetzt die gleiche Leistung, wenn sie auf a gerufen werden &str
. Relevantes Commit: github.com/rust-lang/rust/pull/32586/files
Es gibt verschiedene Möglichkeiten, mehrere Zeichenfolgen zu einer einzelnen Zeichenfolge zu verketten, die durch ein anderes Zeichen getrennt sind.
Das Schönste, was ich gesehen habe, ist die Verwendung der join
Methode für ein Array:
fn main() {
let a = "Hello";
let b = "world";
let result = [a, b].join("\n");
print!("{}", result);
}
Abhängig von Ihrem Anwendungsfall bevorzugen Sie möglicherweise auch mehr Kontrolle:
fn main() {
let a = "Hello";
let b = "world";
let result = format!("{}\n{}", a, b);
print!("{}", result);
}
Es gibt einige weitere manuelle Methoden, die ich gesehen habe, einige, die hier und da ein oder zwei Zuordnungen vermeiden. Aus Gründen der Lesbarkeit halte ich die beiden oben genannten für ausreichend.
join
ist tatsächlich mit dem SliceContactExt
Merkmal verbunden . Das Merkmal ist als instabil markiert, aber seine Methoden sind stabil und im Prelude enthalten, sodass sie standardmäßig überall verwendet werden können. Das Team scheint sich bewusst zu sein, dass dieses Merkmal nicht existieren muss, und ich kann mir vorstellen, dass sich die Dinge in Zukunft damit ändern werden.
Ich denke diese concat
Methode und +
sollte auch hier erwähnt werden:
assert_eq!(
("My".to_owned() + " " + "string"),
["My", " ", "string"].concat()
);
und es gibt auch concat!
Makro, aber nur für Literale:
let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");
+
wird bereits in einer bestehenden Antwort erwähnt . ( Dies ist eine Implementierung des Add
Merkmals , dass ein nimmt , String
wie auf der linken Seite und eine &str
als die rechte Seite: )
In RUST stehen verschiedene Methoden zum Verketten von Zeichenfolgen zur Verfügung
concat!()
):fn main() {
println!("{}", concat!("a", "b"))
}
Die Ausgabe des obigen Codes lautet:
ab
push_str()
und +
Operator):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = "c".to_string();
_a.push_str(&_b);
println!("{}", _a);
println!("{}", _a + &_b);
}
Die Ausgabe des obigen Codes lautet:
ab
ABC
Using format!()
):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = format!("{}{}", _a, _b);
println!("{}", _c);
}
Die Ausgabe des obigen Codes lautet:
ab
Probieren Sie es aus und experimentieren Sie mit Rust Spielplatz
str
und&str
sind verschiedene Typen und für 99% der Zeit, sollten Sie nur kümmern uns um&str
. Es gibt andere Fragen, die die Unterschiede zwischen ihnen detailliert beschreiben.