【问题标题】:Rust cannot return value referencing local variable on HashMap getRust 无法返回引用 HashMap get 上的局部变量的值
【发布时间】:2021-05-17 07:41:43
【问题描述】:

我的代码如下所示:

use std::collections::HashMap;

fn main() {
    let x = get_hash_map();
    println!("{:?}", x);
}

fn get_hash_map() -> Option<&'static Vec<i32>> {
    let mut hm = HashMap::new();
    let mut vec = Vec::new();
    vec.push(1);
    hm.insert("1".to_string(), vec);
    return hm.get("1");
}

但是我收到了这个错误:

error[E0515]: cannot return value referencing local variable `hm`
  --> src/main.rs:13:12
   |
13 |     return hm.get("1");
   |            --^^^^^^^^^
   |            |
   |            returns a value referencing data owned by the current function
   |            `hm` is borrowed here

这里是生锈游乐场:https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=7605176aee2dd3ff77a0cfd04a89db55

任何人都可以建议最低限度地解决此问题的替代方法吗?谢谢!

【问题讨论】:

  • 你的 hashmap 是本地的。它在函数结束时不再存在。你想做什么?

标签: rust rust-cargo


【解决方案1】:
fn get_hash_map() -> Option<&'static Vec<i32>> {
    let mut hm = HashMap::new();
    let mut vec = Vec::new();
    vec.push(1);
    hm.insert("1".to_string(), vec);
    return hm.get("1");
}

这是无效的,因为您已声明您将返回 Option&lt;&amp;'static Vec&lt;i32&gt;&gt;,但您返回的是 Option&lt;&amp;'a Vec&lt;i32&gt;&gt;,其中 'a 是当前函数的生命周期。一旦函数返回,HashMap 将停止存在,释放向量,然后引用将变得悬空。这正是借用检查器旨在避免的情况。

只需按值返回向量:

fn get_hash_map() -> Option<Vec<i32>> {
    let mut hm = HashMap::new();
    let mut vec = Vec::new();
    vec.push(1);
    hm.insert("1".to_string(), vec);
    return hm.remove("1");
}

remove 将值移出映射,将其作为Option&lt;V&gt; 返回。

如果您随后需要Option&lt;&amp;Vec&lt;i32&gt;&gt;,您只需在Option&lt;Vec&lt;i32&gt;&gt; 上使用as_ref() 即可获得。永远记住,一旦它的值超出范围,它就会失效。

【讨论】:

  • remove() 取消了HashMap 的作用以及 OP 问题中引用的生命周期。如果有另一个代码块/段落与之相关,它可能会提供更多信息。
  • @sebpuetz 鉴于目前还不清楚 OP 想要做什么,remove() 是实现 OP 想要的唯一合理方法,而无需完全更改他发布的 sn-p。我认为这里的引用被错误地使用了,而 OP 可能想要的只是知道他必须按值返回东西。
【解决方案2】:

HashMap hmget_hash_map() 函数的范围内是本地的,并且在 get_hash_map() 返回时立即被删除。 hm.get("1") 返回的值包含对这个HashMap 的引用,因此它的生命周期也与get_hash_map() 的范围相关联,不幸的是,它比指定的'static 生命周期短。

如果您删除 'static 生命周期并将其替换为函数上的一些 'a 注释,您会收到类似的错误,因为再次没有(合理)方法可以从创建该数据的所有者。

但是,您可以在周围范围内创建地图并通过对get_hash_map 的可变引用将其传递给

use std::collections::HashMap;

fn main() {
    let mut hm = HashMap::new();
    let x = get_hash_map(&mut hm);
    println!("{:?}", x);
}

// note that both `hm` and the reference in the return type have the same 'a lifetime.
fn get_hash_map<'a>(hm: &'a mut HashMap<String, Vec<i32>>) -> Option<&'a Vec<i32>> {
    let mut vec = Vec::new();
    vec.push(1);
    hm.insert("1".to_string(), vec);
    hm.get("1");
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多