尝试实现查找或插入时 HashMap 借用问题

2024-05-17

我尝试实现自己的类似物find_or_insert方法看起来像这样:

use std::collections::HashMap;

pub struct SomeManager {
    next: i32,
    types: HashMap<i32, i32>,
}

impl SomeManager {
    pub fn get_type<'a>(&'a mut self, k: i32) -> &'a i32 {
        match self.types.get(&k) {
            Some(ref x) => return *x,
            None => {
                self.types.insert(k, self.next);
                self.next += 1;
                return self.types.get(&k).unwrap();
            }
        }
    }
}

fn main() {}

Error:

error[E0502]: cannot borrow `self.types` as mutable because it is also borrowed as immutable
  --> src/main.rs:13:17
   |
10 |         match self.types.get(&k) {
   |               ---------- immutable borrow occurs here
...
13 |                 self.types.insert(k, self.next);
   |                 ^^^^^^^^^^ mutable borrow occurs here
...
18 |     }
   |     - immutable borrow ends here

我知道有一些标准方法可以实现此功能,但我希望此方法尽可能轻 - 它将被非常频繁地调用,并且几乎所有时间值都已经存在。

据我了解,当我们打电话时self.types.get我们借用它的范围match声明,所以我们无法调用self.types.insert这里。我尝试过将方法从None分支出match声明,但它也失败了。

我发现的唯一可行的解​​决方案需要调用get twice:

pub fn get_type<'a>(&'a mut self, k: i32) -> &'a i32 {
    let is_none = match self.types.get(&k) {
        Some(ref x) => false,
        None => true,
    };
    if is_none {
        self.types.insert(k, self.next);
        self.next += 1;
    }
    self.types.get(&k).unwrap()
}

我该如何解决这种情况?


有以下几种方法HashMap来实现这些复杂的情况。最值得注意的是,对于你的情况,HashMap::entry https://doc.rust-lang.org/std/collections/struct.HashMap.html#method.entry and Entry::or_insert_with https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.or_insert_with:

pub fn get_type<'a>(&'a mut self, k: i32) -> &'a i32 {
    self.types.entry(k).or_insert_with(|| {
        let value = self.next;
        self.next += 1;
        value
    })
}

然而,就你而言,有借用self里面,所以不行。

因此,我们将借用self.next在闭包之外,因此编译器可以将其推断为与self.types。问题应该只通过一次查找就解决了。

pub fn get_type<'a>(&'a mut self, k: i32) -> &'a i32 {
    let next = &mut self.next;

    self.types.entry(k).or_insert_with(|| {
        let value = *next;
        *next += 1;
        value
    })
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

尝试实现查找或插入时 HashMap 借用问题 的相关文章

随机推荐

  • 在测试中捕获 Flask 中止状态代码?

    我在基于 Flask 类的视图中有一个 abort 我可以断言已调用中止 但我无法在上下文管理器中访问 406 代码 views py from flask views import View from flask import abort
  • 如何对 Prism / MEF 中的 ItemsControl 中的视图进行排序?

    我使用 prism v4 和 MEF 来加载我的模块 我的模块包含一些视图 MVVM 这些视图由 MEF 自动加载到 ItemsControl NavigationRegion 中 这很好用 所有项目都显示在 ItemControl 中 但
  • javascript setInterval 不适用于对象

    所以 我正在尝试创建一个 javascript 对象 并使用 setInterval 方法 这似乎不起作用 如果我删除引号 则该方法将运行一次 有什么想法吗 另外 我正在使用 Jquery Yacoby 和
  • 将随机字节转换为整数范围 - 如何?

    我试图通过读取 crypto randomBytes 来获取一定范围内的随机整数 现在 我的问题是我不知道如何从该字节流中读取整数 我想生成一个范围只是 丢弃 不在范围内的整数的问题 有任何想法吗 您可以从以下位置获取一个 32 位整数cr
  • 使用 CSS Grid,从任何地方滚动 div(不使用 jQuery 插件)

    div 怎样才能 scroll content https jsfiddle net blehmanade x1k3rhj7 33 可以从页面上的任何位置滚动吗 现在 scroll content仅当鼠标位于其上方时才可滚动 但是 当鼠标位
  • 海量矢量资源导入Android Studio

    有没有办法将许多矢量 svg 图像导入到项目中 导入 30 多个图标有点无聊而且相当愚蠢 Android Studio 使用哪个脚本来转换 svgs 现在 Android Studio 中可以实现这一点 在左侧的资源管理器中 效果很好
  • 通过 SQLAlchemy 获取随机行

    如何使用 SQLAlchemy 从表中选择一个或多个随机行 这在很大程度上是一个特定于数据库的问题 我知道 PostgreSQL SQLite MySQL 和 Oracle 具有通过随机函数排序的能力 因此您可以在 SQLAlchemy 中
  • 使用 Pyomo 的旅行推销员

    我正在尝试使用 pyomo 来解决 TSP 问题 我已经使用 python 和 Gurobi 成功实现了 但是我的 Gurobi 许可证已过期 所以我现在想使用 pyomo 和 GLPK 来实现 TSP 问题 这是我到目前为止能想到的 它不
  • 在 qx 运算符中将 perl 数组拆分为单独的参数

    我试图将一组参数传递给qx操作员 考虑 my files qw A txt B txt print qx ls files 这给出了错误 ls cannot access A txt B txt No such file or direct
  • 如何创建可点击的gridview行?

    我想创建一个 gridview 行 其中整行都是可单击的 当我单击该行上的任意位置时 它会打开另一个包含行信息的 aspx 页面 我正在使用 asp net 和 C 任何人都可以帮助我吗 提前致谢 触发 Gridview 的两个事件 OnR
  • 如何设置变量内的浮点精度

    我目前正在编写一个程序 需要将浮点后的四舍五入值计算为仅 2 位数字 说吧 我已经声明了 float a If a 3 555然后它会存储a 3 56 围捕 For a 3 423 a的值是a 3 423 不用找了 我可以这样做来打印输出
  • HTTPS URL 的基本代理身份验证返回 HTTP/1.0 407 需要代理身份验证

    我想在 Java 中使用具有基本身份验证 用户名 密码 的代理来进行连接 并且仅此连接 以下代码适用于 HTTP URL 例如 http www google com http www google com URL url new URL
  • 如何使用scala获取elasticsearch中_delete_by_query api的状态

    我正在 scala 中向 elasticsearch 发送 HTTP post Http s http elkIp 5051 indexName delete by query postData s query terms zip id k
  • 具有连字符的 Oracle 正则表达式在 Windows 上给出的结果与在 Unix 上不同

    我有以下带有正则表达式的查询 select REGEXP REPLACE TEST 3304 V2 lt gt as REG from dual 当通过 SQL Plus 在Windows机器返回以下内容 SQL gt select REG
  • primefaces 二维码未显示?

    I am using primefaces to develop a web app I am trying to show the bar code on mhe webpage All coders are shown except t
  • Visual Studio 2010 中的 SOIL 设置

    我无法得到SOIL http www lonesock net soil html正确使用 Visual Studio 2010 我远非 VS 专家 但据我所知 只需执行以下步骤即可使环境正常运行 属性 gt gt C C gt 常规 gt
  • Matlab的导入函数的范围是什么?

    我正在尝试将一些用 Matlab 编写的代码转换为独立的 编译的 Matlab 应用程序 然而 在出现一些奇怪的错误之后 我意识到代码大量使用了从路径中添加和删除的操作 以避免多次使用多个具有相同名称 但结果 计算不同 的函数这一事实 环顾
  • matplotlib 图形的乳胶渲染文本中的中心标题

    我想将 Matplotlib 图形的标题居中 其中在渲染 LaTeX 样式时包含换行符返回 在标题中间插入 Latex 的简单返回代码可以工作 但不会使其居中 从而导致换行符从第一行尴尬地移动 from matplotlib import
  • 选中复选框时如何向文本区域添加值

    我正在使用我刚刚在 SO 上找到的以下函数 该函数可以解决我的问题 只有一个问题是 我有一长串选择列表 当用户选中超过 3 4 个复选框时 某些文本或添加到文本区域的值不再可见 有没有什么方法可以让每次选中一个框时添加到文本区域的文本始终可
  • 尝试实现查找或插入时 HashMap 借用问题

    我尝试实现自己的类似物find or insert方法看起来像这样 use std collections HashMap pub struct SomeManager next i32 types HashMap