Come concatenare le stringhe?


199

Come concatenare le seguenti combinazioni di tipi:

  • str e str
  • String e str
  • String e String

14
Si noti che 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.
Shepmaster,

Risposte:


235

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!


2
Cosa ne pensi di Add/ +simbolo? Potresti coprirlo se vuoi.
bluss

Forse è abbastanza semplice, ma capire che richiede guardare le possibili firme di tipo per Aggiungi con stringa.
bluss

Grazie! Sei in grado di approfondire leggermente il modo in cui & String può essere definito come & str? Quale parte della sua implementazione lo consente e / o dove lo dice nel documento?
jsalter,

1
@jsalter è un argomento piuttosto separato, quindi potrebbe essere utile come un'altra domanda di alto livello. Ho aggiornato per collegarmi ai documenti appropriati (il più vicino possibile, almeno ...)
Shepmaster,

10
@ChrisMorgan Va notato che la discrepanza .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
chad

49

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.


Dove è joindocumentato? Sembra stare a metà strada tra una matrice e una stringa. Ho cercato nella documentazione dell'array e sono stato rapidamente confuso.
Duane J,

3
@DuaneJ 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.
Simon Whitehead,

9

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: )
Shepmaster

È vero, la risposta esistente è così ampia che non me ne sono accorto.
Susan

6

Semplici modi per concatenare le stringhe in RUST

Esistono vari metodi disponibili in RUST per concatenare le stringhe

Primo metodo (utilizzando concat!()):

fn main() {
    println!("{}", concat!("a", "b"))
}

L'output del codice sopra è:

ab


Secondo metodo (utilizzo 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


Terzo metodo ( 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


Questa risposta non aggiunge nulla di nuovo alle risposte esistenti.
Shepmaster
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.