3

我有一个基本的(可能是愚蠢的)所有权问题。我正在尝试创建一个来自包装在里面的&strString的向量Some(String)。我正在使用一个中间变量来存储提取/解包String,似乎我需要在向量之前定义这个中间变量以满足借用检查器:

工作代码:

fn main() {
    let a = Some("a".to_string());

    let mut val = String::new();
    let mut v = Vec::<&str>::new();

    if a.is_some() {
        val = a.unwrap();
        v.push(&val[..]);
    }
    println!("{:?}", val);
}

非工作代码:

fn main() {
    let a = Some("a".to_string());

    let mut v = Vec::<&str>::new();
    let mut val = String::new();

    if a.is_some() {
        val = a.unwrap();
        v.push(&val[..]);
    }
    println!("{:?}", val);
}

和编译器错误:

<anon>:9:17: 9:20 error: `val` does not live long enough
<anon>:9         v.push(&val[..]);
                        ^~~
<anon>:4:35: 12:2 note: reference must be valid for the block suffix following statement 1 at 4:34...
<anon>:4     let mut v = Vec::<&str>::new();
<anon>:5     let mut val = String::new();
<anon>:6 
<anon>:7     if a.is_some() {
<anon>:8         val = a.unwrap();
<anon>:9         v.push(&val[..]);
        ...
<anon>:5:32: 12:2 note: ...but borrowed value is only valid for the block suffix following statement 2 at 5:31
<anon>:5     let mut val = String::new();
<anon>:6 
<anon>:7     if a.is_some() {
<anon>:8         val = a.unwrap();
<anon>:9         v.push(&val[..]);
<anon>:10     }
        ...
error: aborting due to previous error
playpen: application terminated with error code 101

游戏围栏代码

问题是:为什么我必须val在向量之前定义变量v?如我所见,val范围与范围相同v,还是我遗漏了什么?

4

1 回答 1

3

绑定以声明的相反顺序被丢弃,即最近声明的事物首先被销毁。具体来说,在不起作用的代码中,析val构函数在v. 如果不仔细考虑做什么Vec<&str>::drop(),这是不安全的:例如,它可以尝试查看它包含的字符串切片的内容,尽管事实上String它们派生的部分已经被破坏。

Vec实际上并没有这样做,但其他合法类型会按照这些方式做一些事情。以前不可能安全地实现Drop包含生命周期/借用指针的类型。一个相对较新的变化通过引入这些额外的限制使其安全。

请注意,如果您声明let v, val;let val, v;稍后分配,则两个绑定确实具有相同的生命周期,因此具有相同生命周期的两个变量并非不可能。

于 2015-03-06T12:57:31.160 回答