对于发生此错误后的生命,我完全感到困惑:

#![feature(collections)]
use std::collections::BitVec;
use std::collections::HashSet;

fn main() {
    let mut hs = HashSet::new();

    let  zeros :  BitVec = BitVec::from_elem(10,false);
    let  ones  :  BitVec = BitVec::from_elem(10,true);
    println!("{:?}\n{:?}",zeros,ones);
    // let mut hs = HashSet::new(); // works only if move this line to #7

    hs.insert(&zeros);
    hs.insert(&ones);
    println!("{:?}",hs);
}

这给了我错误:
<anon>:14:16: 14:21 error: `zeros` does not live long enough
<anon>:14     hs.insert(&zeros);
                         ^~~~~
<anon>:7:33: 17:2 note: reference must be valid for the block suffix following statement 0 at 7:32...
<anon>:7     let mut hs = HashSet::new();

但是,如果我稍后在hszeros之后声明ones,则一切正常:
#![feature(collections)]
use std::collections::BitVec;
use std::collections::HashSet;

fn main() {
    // let mut hs = HashSet::new();

    let  zeros :  BitVec = BitVec::from_elem(10,false);
    let  ones  :  BitVec = BitVec::from_elem(10,true);
    println!("{:?}\n{:?}",zeros,ones);
    let mut hs = HashSet::new(); // works only if move this line to #7

    hs.insert(&zeros);
    hs.insert(&ones);
    println!("{:?}",hs);
}

输出:
0000000000
1111111111
{0000000000, 1111111111}
Program ended.

您可以尝试代码here

--

我在IRC上问这个问题得到了以下答案:

最佳答案

hs的类型是HashSet<&'ρ BitVec>-但是是什么?

错误消息对此进行了一些解释:

<anon>:7:33: 17:2 note: reference must be valid for the block suffix following statement 0 at 7:32...
<anon>:7     let mut hs = HashSet::new();

就是说,对于定义了HashSet的第7行之后的其余块,该引用必须是合法的。

那就是的含义:第7行之后的块的其余部分。

这样想:在创建HashSet<&BitVec>时,立即插入值是否合法?不,因为它们是对尚不存在的事物的引用。

如果您插入的是BitVec而不是对它们的引用,则问题将消失,因为&'ρ BitVec的生存期为BitVec的生存期为'static,因为它不包含非静态数据,因此插入hs.insert(BitVec::from_elem(10, false))将是正好。

现在,为什么编译器不允许早期的hs定义?推断类型时,它必须是合法的类型。如果要在hs声明位于第7行时推断出“第13行之后”的生存期,则在声明该声明时将有一些不合法的内容。在这种特殊情况下,对T调用中的HashSet<T>new并没有执行任何操作,因此您可以说理论上编译器可以忽略这样的事实,即它正在处理的非法类型将在我们实际使用时变为合法,但是这将是彻头彻尾的邪恶和前后矛盾(对函数主体的更改可能会影响调用者),因此Rust禁止整个行为。

10-02 03:11