如何转移字符串的所有权?

8

我刚接触 Rust,遇到了几次类似以下问题的困扰:

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(假设我不想在向量中变异项本身)?

1个回答

8
给向量传递一个字符串而不是引用一个字符串。一个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);
    }
}

在你的例子中,你在 for 循环体内分配了一个字符串 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
1
let as_str: Vec<_> = (1..6).map(|i| i.to_string()).collect() 是另一种实现 OP 所需求的方法。 - Akavall

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接