我正在计算一个单词出现在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);
}
生锈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()
可以解决它。当问题为l
时,我不明白为什么Rust编译器将责任归咎于w
。我怎么能推断w
这里的问题是什么?
答案 0 :(得分:9)
指责
l
不是,真的。再次查看错误消息:
for w in l.unwrap().split_whitespace() {
---------- temporary value created here
错误标记指向unwrap
上l
的来电。
问题是
时w
不是,真的。 l
的类型为Result<String>
。当您致电unwrap
时,您会收到String
,然后split_whitespace
会返回对该字符串的引用。这些引用仅与字符串一样存在,但是您的代码会尝试将它们放入一个比字符串更长寿的散列映射。问题是 l.unwrap()
的寿命不够长,而w
只是对不能活得足够长的东西的引用。< / p>
从概念上讲,它与此代码的问题相同:
use std::collections::HashMap;
fn main() {
let mut counts = HashMap::new();
{
let s = String::from("hello world");
counts.insert(&s, 0);
}
println!("{:?}", counts);
}
其中也指向s
,并表示它的寿命不长(因为它没有)。
正确的解决方案是将每个单词转换为String
所拥有的HashMap
所拥有的{/ 1}}:
for l in reader.lines() {
for w in l.unwrap().split_whitespace() {
counts.entry(w.to_string()).or_insert(0) += 1;
}
}
答案 1 :(得分:5)
错误在这里是对的。 l
会受到指责,因为只有w
{和l
} l.unwrap()
并且l
的生命时间不足以将其置于endDateObj.setMonth(startDateObj.getMonth() + monthsToBeAdded);
之内,var startDate = $('.pickupDate').datepicker('getDate');
var endDate = new Date();
endDate.setDate(startDate.getMonth() + monthsToAdd);
$('input').val(endDate);
才会生存更高范围的hashmap。
在实践中,您只需要查看其他变量取决于编译器抱怨的变量的生命周期。
但Rust最近也在改进错误报告,所以我raise this case as potential bug。