2014-06-11 12 views

risposta

212

String è il tipo di stringa heap dinamico, come Vec: utilizzarlo quando è necessario possedere o modificare i dati di stringa.

str è una sequenza immutabile di byte UTF-8 di lunghezza dinamica da qualche parte nella memoria. Poiché la dimensione è sconosciuta, è possibile gestirla solo dietro un puntatore, ovvero str più comunemente viene visualizzato come &str: un riferimento ad alcuni dati UTF-8, normalmente chiamati "string slice" o solo una "slice". Una sezione è solo una vista su alcuni dati e tali dati possono essere ovunque, ad es.

  • in memoria statica: una stringa letterale "foo" è una &'static str. I dati sono codificati nel file eseguibile e caricati in memoria quando viene eseguito il programma.
  • all'interno di un heap assegnato String: String dereferences to a &str view dei dati di String.
  • in pila: ad es. la seguente crea un array di byte di stack-assegnati, e poi si fa un view of that data as a &str:

    use std::str; 
    
    let x: &[u8] = &[b'a', b'b', b'c']; 
    let stack_str: &str = str::from_utf8(x).unwrap(); 
    

In sintesi, utilizzare String se avete bisogno posseduto dati stringa (come passare le stringhe ad altri compiti, o la loro costruzione in fase di esecuzione) e utilizzare &str se è necessaria solo la visualizzazione di una stringa.

Questo è identico al rapporto tra un vettore Vec<T> e una fetta &[T], ed è simile al rapporto tra by-value T e per riferimento &T per tipi generali.


A str è lunghezza fissa; non è possibile scrivere byte oltre la fine o lasciare byte finali non validi. Poiché UTF-8 è una codifica a larghezza variabile, ciò impone l'immutabilità a tutti gli str s. In generale, la mutazione richiede la scrittura di più o meno byte rispetto a prima (ad esempio, la sostituzione di ä (2+ byte) con uno ä (2+ byte) richiede più spazio nello str).

Al momento può solo apparire come &str, ma dynamically sized types possono consentire cose come Rc<str> per una sequenza di riferimento contati UTF-8 byte. Inoltre, non è possibile, str non si adatta perfettamente allo schema DST, poiché non esiste ancora una versione a dimensione fissa.

+4

"sequenza di UTF-8 byte (** di lunghezza sconosciuta **) "- è scaduto? [Docs] (https://doc.rust-lang.org/nightly/std/primitive.str.html) dice "A' & str' è costituito da due componenti: un puntatore ad alcuni byte e una lunghezza. " – mrec

+3

Non è scaduto (la rappresentazione è stata abbastanza stabile), solo un po 'imprecisa: non è statisticamente conosciuta, diversamente da, ad esempio, '[u8; N] '. – huon

+1

@mrec è sconosciuto al momento della compilazione, non è possibile formulare ipotesi su di esso, ad esempio, quando si crea uno stack frame. Quindi perché è spesso trattato come riferimento, che un riferimento è una dimensione nota in fase di compilazione, che è la dimensione di un puntatore. – Sekhat

27

str, utilizzato solo come &str, è una sezione di stringa, un riferimento a un array di byte UTF-8.

String è quello che era ~str, un array di byte UTF-8 espandibile di proprietà.

22

Ho un C++ sfondo e l'ho trovato molto utile per pensare String e &str in termini C++:

  • una ruggine String è come un std::string; possiede la memoria e fa il lavoro sporco di gestire la memoria.
  • A Rust &str è come un char* (ma un po 'più sofisticato); ci indica l'inizio di un blocco nello stesso modo in cui puoi ottenere un puntatore del contenuto di std::string.

I due stanno per scomparire? Io non la penso così. Servono a due scopi:

String mantiene il buffer ed è molto pratico da utilizzare. &str è leggero e dovrebbe essere usato per "guardare" nelle stringhe. È possibile cercare, dividere, analizzare e persino sostituire i blocchi senza la necessità di allocare nuova memoria.

&str può guardare all'interno di un String come può puntare a qualche stringa letterale. Il seguente codice ha bisogno di copiare la stringa letterale nella memoria String gestito:

let a: String = "hello rust".into(); 

Il seguente codice consente di utilizzare il letterale stesso, senza copia (solo lettura però)

let a: &str = "hello rust"; 
+0

come una string_view? –

Problemi correlati