“借来的价值活得不够久"似乎责怪错误的事情 [英] "borrowed value does not live long enough" seems to blame the wrong thing

查看:33
本文介绍了“借来的价值活得不够久"似乎责怪错误的事情的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在计算一个单词在 Macbeth 中出现的次数:

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() {
    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);
}

Rust 对此嗤之以鼻,说:

Rust barfs on this, saying:

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 是这里的问题?

The actual problem is that w is a reference, and so changing it to w.to_string() solves it. I don't get why the Rust compiler is pointing the blame at l, when the issue is w. How am I supposed to infer that w is the problem here?

推荐答案

将责任归咎于l

这不是,真的.再次查看错误消息:

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

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

错误标记指向 l 上的 unwrap 调用.

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

当问题是 w

这不是,真的.lResult 类型.当您调用 unwrap 时,您会得到一个 String,然后 split_whitespace 返回对该字符串的引用.这些引用仅与字符串一样长,但您的代码尝试将它们放入一个比字符串寿命更长的哈希图中.问题是 l.unwrap() 的寿命不够长,而 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);
}

这也指向 s 并说它的寿命不够长(因为它没有).

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

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

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

这篇关于“借来的价值活得不够久"似乎责怪错误的事情的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆