我是Rust的新手,正在为leetcode问题研究Rust解决方案,“49。组Anagrams”,并遇到了一个问题,一个借来的价值没有生存足够长的错误。
还有一些其他相关的SOF线程,但我有困难理解的内容。
错误:
error[E0597]: `key` does not live long enough
--> src/main.rs:14:18
|
9 | let key: String = sort_letters(&w);
| --- binding `key` declared here
10 |
11 | if map.contains_key(&key as &str) {
| --- borrow later used here
...
14 | map.insert(&key as &str, val);
| ^^^^ borrowed value does not live long enough
...
20 | }
| - `key` dropped here while still borrowed
fn main() {
use std::any::type_name;
use std::collections::HashMap;
let words: Vec<&str> = vec!["eat", "tea", "tan", "ate", "nat", "bat"];
let mut map: HashMap<&str, Vec<&str>> = HashMap::new();
for w in words {
let key: String = sort_letters(&w);
if map.contains_key(&key as &str) {
let mut val: Vec<&str> = map.get(&key as &str).unwrap().to_vec();
val.push(w);
map.insert(&key as &str, val);
} else {
let mut val = Vec::new();
val.push(w);
map.insert(&key as &str, val);
}
}
}
fn sort_letters(w: &str) -> String {
let mut chars: Vec<char> = w.chars().collect();
chars.sort();
chars.into_iter().collect::<String>()
}
我试着克隆这个键来给&键给予新的所有权,但这给了我同样的错误。
1条答案
按热度按时间ct3nt3jp1#
好的,我们将有一个Map,但这个Map不会拥有它的键:键将是对由其他东西拥有的字符串的引用。
现在我们循环一些单词,在每次迭代中,我们创建一个包含单词字母的字符串。(顺便说一句:不需要用类型
String
注解key
,rust足够聪明,可以解决这个问题)。该字符串值由变量
key
拥有,这意味着当它超出范围时(在循环迭代结束时),该字符串将被删除。然后几行之后,我们向Map添加一个条目,键是对同一个字符串值的引用(它实际上发生在if语句的两个分支中,为了简单起见,我只显示一个)。
然后是循环的结束。变量
key
超出作用域,值被删除-但Map仍然引用它!解决方案是让map拥有key,就像这样:
然后循环看起来像这样:
这将工作,但它是非常低效的。
to_vec
在map中创建Vec
的副本,然后我们将新单词添加到Vec
的末尾,并将新的Vec
放回map中。我们不断地创建新的Vec
s,并将旧值复制到新值。有一个更简单更好的方法。
HashMap
有另一个方法entry
,它允许您非常干净地实现“查找或插入条目”模式。使用entry
,你的循环看起来像这样:entry
方法返回一个Entry
结构体,如果条目不存在,该结构体有各种方法来填充条目。它还为我们提供了对新条目或现有条目的可变访问,我们可以直接将单词推到上面。