“borrowed value does not live long enough” seems to blame the wrong thing

后端 未结 2 1403
生来不讨喜
生来不讨喜 2020-11-27 08:13

I am counting the number of times a word appears in Macbeth:

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

fn main()          


        
相关标签:
2条回答
  • 2020-11-27 08:41

    The error is both right and wrong here. l is blamed, because w lives only as long as l (and l.unwrap()) and l doesn't live long enough to put it in hashmap in a higher scope.

    In practice, you just have to look at what other variables depend on the lifetime of a variable the compiler complains about.

    But Rust is also working lately on improving error reporting, so I'd raise this case as potential bug.

    0 讨论(0)
  • 2020-11-27 08:45

    is pointing the blame at l

    It's not, really. Review the error message again:

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

    The error marker is pointing to the call of unwrap on l.

    when the issue is w

    It's not, really. l is of type Result<String>. When you call unwrap, you get a String, and then split_whitespace returns references to that string. These references live only as long as the string, but your code tries to put them into a hashmap that will live longer than the string. The problem is that the l.unwrap() doesn't live long enough, and w is just a reference to the thing that doesn't live long enough.

    Conceptually, it's the same problem as this code:

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

    Which also points to s and says it doesn't live long enough (because it doesn't).

    The correct solution is to convert each word into an owned String which the HashMap can then hold:

    for l in reader.lines() {
        for w in l.unwrap().split_whitespace() {
            counts.entry(w.to_string()).or_insert(0) += 1;
        }
    }
    
    0 讨论(0)
提交回复
热议问题