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

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;
    }
}

Leave a Comment