2015-08-21 17 views
5

Sono nuovo di ruggine ed ho incontrato un problema simile al seguente un paio di volte:Come trasferisco la proprietà delle stringhe?

fn main() { 
    let mut as_str: Vec<&String> = Vec::new(); 
    for i in [1, 2, 3, 4, 5].iter() { 
     let i_str = i.to_string(); 
     as_str.push(&i_str); 
    } 
} 

da cui si ricava il seguente errore:

<anon>:6:22: 6:27 error: `i_str` does not live long enough 
<anon>:6   as_str.push(&i_str); 
          ^~~~~ 

Come faccio a trasferire la proprietà della stringa il vettore (non voglio copiare)? Ho bisogno di una vita? Dovrebbe essere una str o una stringa (supponendo che non vogliano mutare gli elementi stessi nel vettore)?

risposta

7

Dare al vettore uno String, non un riferimento a uno. A Foo è di proprietà, viene preso in prestito un &Foo.

fn main() { 
    let mut as_str: Vec<String> = Vec::new(); 
    for i in [1, 2, 3, 4, 5].iter() { 
     let i_str = i.to_string(); 
     as_str.push(i_str); 
    } 
} 

Nel tuo esempio, si assegnano un String all'interno del corpo del ciclo per, poi prendendo un riferimento ad esso. Poiché nulla possiede il numero String, viene rilasciato alla fine del corpo del ciclo. Ciò significa che tutti i riferimenti diventerebbero non validi. La ruggine previene questa violazione della sicurezza della memoria.

Nel mondo reale, che non avevo mai necessario specificare il tipo di qui, l'inferenza dei tipi è sufficiente:

fn main() { 
    let mut as_str = Vec::new(); 
    for i in [1, 2, 3, 4, 5].iter() { 
     let i_str = i.to_string(); 
     as_str.push(i_str); 
    } 
} 

E probabilmente avrebbe usato map per convertire una fetta di cose ad un altro:

fn main() { 
    let as_str: Vec<_> = [1, 2, 3, 4, 5].iter().map(|i| i.to_string()).collect(); 
} 

Per inciso, non ha mai senso avere un &String; potresti anche avere un &str.

+1

Giusto per essere sicuri, la stringa viene spostata e non copiata in quel caso corretta? Si deve copiare esplicitamente in Rust (diversamente dal C++)? – gnash

+2

@gnash Sì, è vero. – emlai

+1

'let as_str: Vec <_> = (1..6) .map (| i | i_to_string()). Collect()' è un altro modo per ottenere ciò che OP è dopo. – Akavall

Problemi correlati