为字符串切片扩展借用生命周期

5

我有一个函数用于读取文件,并且对于每一行,将其添加到类型为&strHashSet中,但是我无法弄清楚如何告诉借用检查器增加生命周期。

这是目前我的函数:

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知道我想要保留它的生命周期?


请在提问前先搜索已有的问题,避免重复发帖。此问题已存在于以下链接:http://stackoverflow.com/q/27570978/155423 或 https://dev59.com/g4jca4cB1Zd3GeqPvl6d。 - Shepmaster
我进行了搜索,但没有一个问题能够告诉我如何扩展引用的生命周期,这确实是我的问题所在。 - Cetra
其中一个答案以“你不能”开头,这与您在这里得到的答案相同:“这是不可能的”。 - Shepmaster
2个回答

7
"但是我不知道如何告诉借用检查器增加生命周期。"
这是不可能的。
在C、C++或Rust中,值的生命周期定义为:
- 如果将其绑定到自动变量,则由其词法范围确定 - 如果它分配在堆上,则由其动态范围确定
您可以创建引用此值的变量,并且如果您的引用的生命周期比该值更长,则会存在悬垂引用:
- 在C和C++中,最好不要做任何事情 - 在Rust中,编译器将拒绝编译您的代码
为了验证程序,Rust编译器将要求您对引用的生命周期进行注释;您将使用生命周期注释,例如 '&a T' 中的'a',以命名生命周期,以便记录多个值之间的关系。
这里的关键词是“记录”:生命周期是无形的,不能被影响,生命周期注释'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
}

那么我不应该能够像这样注释引用吗: let line: 'a String = line.unwrap(); let a_ref : &'a str - Cetra
@Cetra:你可以使用'a:(一个标签),但只能在whileforloop前面使用,这样它就可以用于直接从内部循环中断到外部循环。否则,在函数签名中只能引入生命周期名称;正如我所说,大多数时候它们是无形的。 - Matthieu M.

3

reader.lines() 返回一个拥有 String 的迭代器。但是在你的 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
}

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