延长String切片的借用寿命

时间:2016-02-27 05:17:44

标签: rust

我有一个读取文件的函数,并且每行都将其添加到HashSet类型的&str,但我无法确定如何告知借阅检查器增加寿命。

到目前为止,这是我的功能:

fn build_collection_set(reader: &mut BufReader<File>) -> HashSet<&str> {
    let mut collection_set: HashSet<&str> = HashSet::new();

    for line in reader.lines() {
        let line = line.unwrap();
        if line.len() > 0 {
            collection_set.insert(&*line);
        }
    }

    return collection_set;
}

我怎么让Rust知道我想让它更长久?

2 个答案:

答案 0 :(得分:6)

  

但是我不知道如何告诉借阅检查员增加生命周期。

这是不可能的。

C,C ++或Rust中的值的生命周期定义为:

  • 通过其词法范围,如果它绑定到自动变量
  • 通过其动态范围,如果它在堆上分配

您可以创建引用此值的变量,如果您的引用的长度超过该值,则您有一个悬空引用:

  • 在C和C ++中,你最好不要做任何事情
  • 在Rust中,编译器将拒绝编译您的代码

为了验证您的程序,Rust编译器将要求您注释您的引用的生命周期;您将在'a中使用生命周期注释,例如&'a T,它允许命名生命周期,以记录多个值的生命周期之间的关系。

这里的操作词是文档:生命是无形的,无法受到影响,生命周期注释'a只是一个允许引用它的名称。

因此?

每当你发现自己想要延长引用的生命周期时,你应该关注的是延长引用的生命周期...或者只是不使用引用而是使用值。

在这种情况下,一个简单的解决方案是返回String而不是&str

fn build_collection_set(reader: &mut BufReader<File>) -> HashSet<String> {
    let mut collection_set = HashSet::new();

    for line in reader.lines() {
        let line = line.unwrap();
        if line.len() > 0 {
            collection_set.insert(line);
        }
    }

    collection_set
}

答案 1 :(得分:3)

reader.lines()返回拥有的字符串的迭代器。但是在你的for循环中,你将它们转换为借用&str的引用。因此,当迭代器超出范围时,所有借用的引用都将变为无效。考虑使用HashSet<String>,这也是零成本,因为字符串会移动到HashSet中,因此不会被复制。

工作示例

fn build_collection_set(reader: &mut BufReader<File>) -> HashSet<String> {
    let mut collection_set: HashSet<String> = HashSet::new();

    for line in reader.lines() {
        let line = line.unwrap();
        if line.len() > 0 {
            collection_set.insert(line);
        }
    }
    collection_set
}