我正在计算一个单词出现在麦克白的次数:
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 回答
事实并非如此 . 再次查看错误消息:
错误标记指向
l
上unwrap
的调用 .事实并非如此 .
l
的类型为Result<String>
. 当你调用unwrap
时,你得到String
,然后split_whitespace
返回对该字符串的引用 . 这些引用仅与字符串一样存在,但是您的代码会尝试将它们放入一个比字符串更长寿的散列映射 . 问题是l.unwrap()
的寿命不够长,而w
只是对那些活不够久的东西的引用 .从概念上讲,它与此代码的问题相同:
其中也指向
s
并表示它没有't live long enough (because it doesn' t) .正确的解决方案是将每个单词转换为拥有的
String
,然后HashMap
可以保存:错误在这里是对的 .
l
受到指责,因为w
仅在l
(和l.unwrap()
)和l
的活动时间不足以将其放入更高范围的hashmap中 .在实践中,您只需要查看其他变量取决于编译器抱怨的变量的生命周期 .
但Rust最近也在改进错误报告方面,所以我会raise this case as potential bug .