You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

关键修改说明

  1. HashMap类型调整:把HashMap<&str, Vec<&str>>改为HashMap<String, Vec<&str>>,确保HashMap持有key的所有权,而非临时引用。
  2. 逻辑简化:使用if let Some(val) = map.get_mut(&key)直接获取对应value的可变引用,无需克隆整个vec,提升效率。
  3. 所有权转移:插入时直接传入key,将其所有权转移给HashMap,保证key的生命周期与HashMap完全一致,不会被提前销毁。

这样修改后,循环内创建的key会被安全地存储在HashMap中,彻底解决了生命周期不匹配的问题。

内容的提问来源于stack exchange,提问作者EonInfinity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 00:02:48