Risposte:
Quando si concatenano le stringhe, è necessario allocare memoria per archiviare il risultato. Il più semplice per iniziare è Stringe &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);
}
Qui, abbiamo una stringa di proprietà che possiamo mutare. Questo è efficiente poiché potenzialmente ci consente di riutilizzare l'allocazione di memoria. C'è un caso simile per Stringe String, come &String può essere indicato come&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);
}
Dopo questo, another_owned_stringnon viene toccato (non notare alcun mutqualificatore). C'è un'altra variante che consuma il Stringma non richiede che sia mutabile. Questa è un'implementazione del Addtratto che prende a Stringcome lato sinistro e a &strcome lato destro:
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);
}
Si noti che owned_stringnon è più accessibile dopo la chiamata a +.
E se volessimo produrre una nuova stringa, lasciando intatti entrambi? Il modo più semplice è usare format!:
fn main() {
let borrowed_string: &str = "hello ";
let another_borrowed_string: &str = "world";
let together = format!("{}{}", borrowed_string, another_borrowed_string);
println!("{}", together);
}
Nota che entrambe le variabili di input sono immutabili, quindi sappiamo che non vengono toccate. Se volessimo fare la stessa cosa per qualsiasi combinazione di String, possiamo usare il fatto che Stringpuò anche essere formattato:
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);
}
Non è necessario usare format!comunque. Puoi clonare una stringa e aggiungere l'altra stringa alla nuova stringa:
fn main() {
let owned_string: String = "hello ".to_owned();
let borrowed_string: &str = "world";
let together = owned_string.clone() + borrowed_string;
println!("{}", together);
}
Nota : tutte le specifiche di tipo che ho fatto sono ridondanti: il compilatore può inferire tutti i tipi in gioco qui. Li ho aggiunti semplicemente per essere chiari alle persone che non conoscono Rust, poiché mi aspetto che questa domanda sia popolare con quel gruppo!
Add/ +simbolo? Potresti coprirlo se vuoi.
.to_owned()ed .to_string()è stato fissato dal commento di cui sopra grazie alla specializzazione impl. Entrambi hanno ora le stesse prestazioni quando vengono chiamati a &str. Impegno pertinente: github.com/rust-lang/rust/pull/32586/files
Per concatenare più stringhe in una singola stringa, separate da un altro carattere, ci sono un paio di modi.
Il più bello che abbia mai visto è usare il joinmetodo su un array:
fn main() {
let a = "Hello";
let b = "world";
let result = [a, b].join("\n");
print!("{}", result);
}
A seconda del tuo caso d'uso potresti anche preferire un maggiore controllo:
fn main() {
let a = "Hello";
let b = "world";
let result = format!("{}\n{}", a, b);
print!("{}", result);
}
Ci sono altri modi manuali che ho visto, alcuni che evitano una o due allocazioni qua e là. Ai fini della leggibilità trovo che i due precedenti siano sufficienti.
joindocumentato? Sembra stare a metà strada tra una matrice e una stringa. Ho cercato nella documentazione dell'array e sono stato rapidamente confuso.
joinè effettivamente collegato al il SliceContactExttratto . Il tratto è contrassegnato come instabile ma i suoi metodi sono stabili e sono inclusi nel Preludio, quindi sono utilizzabili ovunque per impostazione predefinita. Il team sembra essere ben consapevole che questo tratto non ha bisogno di esistere e immagino che le cose cambieranno in futuro con esso.
Penso che questo concatmetodo +debba essere menzionato anche qui:
assert_eq!(
("My".to_owned() + " " + "string"),
["My", " ", "string"].concat()
);
e c'è anche concat!macro ma solo per i letterali:
let s = concat!("test", 10, 'b', true);
assert_eq!(s, "test10btrue");
+è già menzionato in una risposta esistente . ( Questa è un'implementazione del Addtratto che prende una Stringcome il lato sinistro e una &strcome il lato destro: )
Esistono vari metodi disponibili in RUST per concatenare le stringhe
concat!()):fn main() {
println!("{}", concat!("a", "b"))
}
L'output del codice sopra è:
ab
push_str()e +operatore):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);
}
L'output del codice sopra è:
ab
abc
Using format!()):fn main() {
let mut _a = "a".to_string();
let _b = "b".to_string();
let _c = format!("{}{}", _a, _b);
println!("{}", _c);
}
L'output del codice sopra è:
ab
dai un'occhiata e sperimenta il terreno di gioco Rust
stre&strsono tipi diversi e per il 99% delle volte, dovresti solo preoccupartene&str. Ci sono altre domande che descrivono in dettaglio le differenze tra loro.