首页 文章

“借来的 Value 不够长久”似乎归咎于错误的事情

提问于
浏览
2

我正在计算一个单词出现在麦克白的次数:

use std::io::{BufRead, BufReader};
use std::fs::File;
use std::collections::HashMap;

fn main() {
    let f = File::open("macbeth.txt").unwrap();
    let reader = BufReader::new(f);
    let mut counts = HashMap::new();

    for l in reader.lines() {
        for w in l.unwrap().split_whitespace() {
            let count = counts.entry(w).or_insert(0);
            *count += 1;
        }
    }

    println!("{:?}", counts);
}

生锈barfs,说:

error[E0597]: borrowed value does not live long enough
  --> src/main.rs:14:9
   |
11 |         for w in l.unwrap().split_whitespace() {
   |                  ---------- temporary value created here
...
14 |         }
   |         ^ temporary value dropped here while still borrowed
...
18 | }
   | - temporary value needs to live until here
   |
   = note: consider using a `let` binding to increase its lifetime

实际问题是 w 是一个引用,因此将其更改为 w.to_string() 解决了它 . 当问题是 w 时,我不明白为什么Rust编译器将责任归咎于 l . 我该如何推断 w 是问题?

2 回答

  • 8

    指责l

    事实并非如此 . 再次查看错误消息:

    for w in l.unwrap().split_whitespace() {
                  ---------- temporary value created here
    

    错误标记指向 lunwrap 的调用 .

    当问题出现时

    事实并非如此 . l 的类型为 Result<String> . 当你调用 unwrap 时,你得到 String ,然后 split_whitespace 返回对该字符串的引用 . 这些引用仅与字符串一样存在,但是您的代码会尝试将它们放入一个比字符串更长寿的散列映射 . 问题是 l.unwrap() 的寿命不够长,而 w 只是对那些活不够久的东西的引用 .

    从概念上讲,它与此代码的问题相同:

    use std::collections::HashMap;
    
    fn main() {
        let mut counts = HashMap::new();
    
        {
            let s = String::from("hello world");
            counts.insert(&s, 0);
        }
    
        println!("{:?}", counts);
    }
    

    其中也指向 s 并表示它没有't live long enough (because it doesn' t) .

    正确的解决方案是将每个单词转换为拥有的 String ,然后 HashMap 可以保存:

    for l in reader.lines() {
        for w in l.unwrap().split_whitespace() {
            counts.entry(w.to_string()).or_insert(0) += 1;
        }
    }
    
  • 5

    错误在这里是对的 . l 受到指责,因为 w 仅在 l (和 l.unwrap() )和 l 的活动时间不足以将其放入更高范围的hashmap中 .

    在实践中,您只需要查看其他变量取决于编译器抱怨的变量的生命周期 .

    但Rust最近也在改进错误报告方面,所以我会raise this case as potential bug .

相关问题