Odpowiedzi:
Podczas łączenia łańcuchów należy przydzielić pamięć, aby zapisać wynik. Najłatwiej jest zacząć Stringa &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);
}
Tutaj mamy własny ciąg, który możemy mutować. Jest to wydajne, ponieważ potencjalnie pozwala nam ponownie wykorzystać przydział pamięci. Istnieje podobny przypadek Stringi String, jak &String można wyrejestrować jako&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);
}
Po tym another_owned_stringjest nietknięty (nie ma mutkwalifikatora). Jest jeszcze jeden wariant, który zużywaString ale nie wymaga to być zmienny. Jest to implementacja Addcechy, która przyjmuje Stringjako lewą stronę i &strjako prawą stronę:
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);
}
Pamiętaj, że owned_stringnie jest już dostępny po połączeniu z +.
Co jeśli chcielibyśmy wyprodukować nowy ciąg, pozostawiając oba nietknięte? Najprostszym sposobem jest użycie format!:
fn main() {
let borrowed_string: &str = "hello ";
let another_borrowed_string: &str = "world";
let together = format!("{}{}", borrowed_string, another_borrowed_string);
println!("{}", together);
}
Zauważ, że obie zmienne wejściowe są niezmienne, więc wiemy, że nie są dotykane. Jeśli chcielibyśmy zrobić to samo dla dowolnej kombinacji String, możemy skorzystać z faktu, że Stringmożna również sformatować:
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);
}
Nie musisz jednak używać format!. Możesz sklonować jeden ciąg i dołączyć drugi do nowego:
fn main() {
let owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
let together = owned_string.clone() + borrowed_string;
println!("{}", together);
}
Uwaga - cała specyfikacja typu, którą zrobiłem, jest zbędna - kompilator może wnioskować o wszystkich typach tutaj odtwarzanych. Dodałem je po prostu, aby były jasne dla osób początkujących w Rust, ponieważ spodziewam się, że to pytanie będzie popularne wśród tej grupy!
Add/ +symbol? Możesz to pokryć, jeśli chcesz.
.to_owned()i .to_string()została naprawiona od powyższego komentarza dzięki specjalizacji impl. Oba mają teraz taką samą wydajność, gdy są wywoływane &str. Odpowiednie zatwierdzanie: github.com/rust-lang/rust/pull/32586/files
Aby połączyć wiele ciągów w jeden ciąg oddzielony innym znakiem, istnieje kilka sposobów.
Najmilsze, jakie widziałem, to użycie joinmetody na tablicy:
fn main() {
let a = "Hello";
let b = "world";
let result = [a, b].join("\n");
print!("{}", result);
}
W zależności od przypadku użycia możesz również preferować większą kontrolę:
fn main() {
let a = "Hello";
let b = "world";
let result = format!("{}\n{}", a, b);
print!("{}", result);
}
Widziałem kilka ręcznych sposobów, niektóre unikały jednego lub dwóch przydziałów tu i tam. Dla celów czytelności powyższe dwa są wystarczające.
joinjest właściwie przymocowany do tej SliceContactExtcechy . Cecha jest oznaczona jako niestabilna, ale jej metody są stabilne i są uwzględnione w Preludium, dzięki czemu można je stosować wszędzie domyślnie. Zespół wydaje się być świadomy, że ta cecha nie musi istnieć i myślę, że wraz z nią wszystko się zmieni.
Myślę, że tę concatmetodę +należy również wymienić:
assert_eq!(
("My".to_owned() + " " + "string"),
["My", " ", "string"].concat()
);
i jest też concat!makro, ale tylko dla literałów:
let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");
+jest już wspomniany w istniejącej odpowiedzi . ( Jest to realizacja Addcecha, która trwa Stringjako lewej strony a &strjak po prawej stronie: )
W RUST dostępne są różne metody łączenia łańcuchów
concat!()):fn main() {
println!("{}", concat!("a", "b"))
}
Dane wyjściowe powyższego kodu to:
ab
push_str()i +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);
}
Dane wyjściowe powyższego kodu to:
ab
ABC
Using format!()):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = format!("{}{}", _a, _b);
println!("{}", _c);
}
Dane wyjściowe powyższego kodu to:
ab
sprawdź to i eksperymentuj z placem zabaw Rust
stri&strsą różne rodzaje i do 99% czasu, tylko powinien dbać o&str. Są też inne pytania wyszczególniające różnice między nimi.