2015-05-10 19 views
55

Come faccio a concatenare i seguenti combinazioni di tipi:Come concatenare le stringhe?

  • str e str
  • String e str
  • String e String
+3

Nota che 'str' e' & str' sono * tipi diversi * e per il 99% delle volte, ti interessa solo '& str'. Ci sono altre domande che descrivono le differenze tra loro. – Shepmaster

risposta

73

quando è concatenare le stringhe, è necessario allocare memoria memorizzare il risultato. Il modo più semplice per iniziare è String e &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 in quanto potenzialmente ci consente di riutilizzare l'allocazione di memoria. C'è un caso simile per String e String, come &Stringcan be dereferenced as &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_string è intatta (nota n mut qualificazione). C'è un'altra variante che consuma il String ma non richiede che sia modificabile. Si tratta di un implementation of the Add trait che prende un String come il lato sinistro e un &str come il 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); 
} 

noti che owned_string non è più accessibile dopo la chiamata a + è.

E se volessimo produrre una nuova stringa, lasciandola intatta? Il modo più semplice è quello di utilizzare format!:

fn main() { 
    let borrowed_string: &str = "hello "; 
    let another_borrowed_string: &str = "world"; 

    let together = format!("{}{}", borrowed_string, another_borrowed_string); 
    println!("{}", together); 
} 

Si noti che entrambe le variabili di input sono immutabili, quindi sappiamo che non vengono toccati. Se volessimo fare la stessa cosa per qualsiasi combinazione di String, possiamo utilizzare il fatto che String può 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 dovete usare format! però. È possibile clone one string e aggiungere l'altra stringa per la 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 tipo che ho fatto è ridondante - il compilatore può dedurre tutti i tipi di gioco qui. Li ho aggiunti semplicemente per essere chiari alle persone nuove di Rust, poiché mi aspetto che questa domanda sia popolare con quel gruppo!

+4

Quando hai un '& str',' to_owned() 'dovrebbe essere preferito a' to_string() '; è più efficiente, scavalcando l'infrastruttura 'std :: fmt'. –

+0

@ChrisMorgan assolutamente corretto, ma ho capito che 'to_string' è più immediatamente comprensibile qui, soprattutto perché mi aspetto che questa sia una domanda per principianti con un alto numero di visualizzazioni. Mi capita di preferire "dentro" me stesso^_ ^. – Shepmaster

+1

Cosa ne pensi del simbolo 'Aggiungi' /' + '? Potresti coprirlo se vuoi. – bluss

15

Per concatenare più stringhe in una singola stringa, separate da un altro carattere, ci sono un paio di modi.

Il più bello che ho visto sta utilizzando il metodo join su un array:

fn main() { 
    let a = "Hello"; 
    let b = "world"; 
    let result = [a, b].join("\n"); 

    print!("{}", result); 
} 

A seconda del caso d'uso si potrebbe anche preferire un maggiore controllo:

fn main() { 
    let a = "Hello"; 
    let b = "world"; 
    let result = format!("{}\n{}", a, b); 

    print!("{}", result); 
} 

Ci sono alcuni modi più manuali Ho visto, alcuni evitando una o due allocazioni qua e là. Per motivi di leggibilità, ritengo che i due precedenti siano sufficienti.

+0

Dove viene documentato 'join'? Sembra di stare a metà strada tra una matrice e una stringa. Ho cercato attraverso la documentazione [array] (https://doc.rust-lang.org/std/primitive.array.html) e sono stato rapidamente confuso. –

+1

@DuaneJ 'join' è in realtà collegato a [tratto' SliceContactExt'] (https://doc.rust-lang.org/std/slice/trait.SliceConcatExt.html). Il carattere è contrassegnato come unstable ma i suoi metodi sono stabili e [sono inclusi nel Preludio] (https://doc.rust-lang.org/std/prelude/#prelude-contents) in modo che siano 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. –

Problemi correlati