Rust报错Borrowed value does not live long enough,求解决(LeetCode49)
Rust解决LeetCode「字母异位词分组」的生命周期错误修复
问题描述
作为Rust新手,在解决LeetCode第49题「字母异位词分组」时,遇到了Borrowed value does not live long enough错误。查看相关帖子后仍无法理解,错误信息如下:
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>() }
尝试克隆key以赋予&key新所有权,但错误依旧。
错误原因
问题核心是生命周期不匹配:
- 你定义的
HashMap的key类型是&str,但这个引用指向的是循环内部创建的String(即key变量)。 - 每次循环结束后,
key会被Rust自动销毁(离开作用域),但HashMap里还保留着指向它的引用,这会导致悬空引用——编译器绝不允许这种不安全的情况,因此报错。 - 克隆
key无效,因为克隆出来的还是循环内的String,取的引用生命周期仍然局限于当前循环迭代。
修复方案
最直接的解决方式是让HashMap拥有key的所有权,也就是把key的类型从&str改成String,这样key的生命周期会和HashMap一致,不会被提前销毁。
修改后的完整代码
fn main() { use std::collections::HashMap; let words: Vec<&str> = vec!["eat", "tea", "tan", "ate", "nat", "bat"]; // 将HashMap的key类型改为String,让HashMap持有key所有权 let mut map: HashMap<String, Vec<&str>> = HashMap::new(); for w in words { let key: String = sort_letters(&w); // 用get_mut直接获取可变引用,省去克隆vec的冗余操作 if let Some(val) = map.get_mut(&key) { val.push(w); } else { // 直接将key的所有权转移给HashMap map.insert(key, vec![w]); } } } fn sort_letters(w: &str) -> String { let mut chars: Vec<char> = w.chars().collect(); chars.sort(); chars.into_iter().collect() }
关键修改说明
- HashMap类型调整:把
HashMap<&str, Vec<&str>>改为HashMap<String, Vec<&str>>,确保HashMap持有key的所有权,而非临时引用。 - 逻辑简化:使用
if let Some(val) = map.get_mut(&key)直接获取对应value的可变引用,无需克隆整个vec,提升效率。 - 所有权转移:插入时直接传入
key,将其所有权转移给HashMap,保证key的生命周期与HashMap完全一致,不会被提前销毁。
这样修改后,循环内创建的key会被安全地存储在HashMap中,彻底解决了生命周期不匹配的问题。
内容的提问来源于stack exchange,提问作者EonInfinity
相关产品推荐
相关产品推荐

