2015-08-21 2 views
5

Я новичок в Русте и столкнулись с проблемой, аналогичной следующие несколько раз:Как передать права собственности на строки?

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); 
    } 
} 

Который дает следующее сообщение об ошибке:

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

Как передать право собственности на строку в вектор (не хотите копировать)? Нужна ли мне жизнь? Должна ли она быть str или String (предположим, что я не хочу мутировать сами элементы в векторе)?

ответ

7

Дайте вектору String, а не ссылку на него. A Foo принадлежит, занят &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); 
    } 
} 

В вашем примере, вы выделение String внутри для тела цикла, то, принимая ссылку на него. Поскольку ничего не принадлежит String, он падает в конце тела цикла. Это означает, что любые ссылки станут недействительными. Rust предотвращает это нарушение безопасности памяти.

В реальном мире, вы никогда не должны указать тип здесь, умозаключение типа достаточно:

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); 
    } 
} 

И вы бы, вероятно, использовать map конвертировать одну часть вещей в другой:

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

Кстати, никогда не имеет смысла иметь &String; вы можете также иметь &str.

+1

Просто убедитесь, что строка перемещена и не скопирована в этом случае правильно? Нужно ли явно копировать в Rust (в отличие от C++)? – gnash

+2

@gnash Да, это так. – emlai

+1

'let as_str: Vec <_> = (1..6) .map (| i | i.to_string()). Collect()' - это еще один способ добиться того, что происходит после OP. – Akavall

Смежные вопросы