热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何遍历Hashmap,打印键/值并删除Rust中的值?

如何解决《如何遍历Hashmap,打印键/值并删除Rust中的值?》经验,为你挑选了2个好方法。

这在任何语言中都应该是一项微不足道的任务.这不适用于Rust.

use std::collections::HashMap;

fn do_it(map: &mut HashMap) {
    for (key, value) in map {
        println!("{} / {}", key, value);
        map.remove(key);
    }
}

fn main() {}

这是编译器错误:

error[E0382]: use of moved value: `*map`
 --> src/main.rs:6:9
  |
4 |     for (key, value) in map {
  |                         --- value moved here
5 |         println!("{} / {}", key, value);
6 |         map.remove(key);
  |         ^^^ value used here after move
  |
  = note: move occurs because `map` has type `&mut std::collections::HashMap`, which does not implement the `Copy` trait

为什么要试图移动参考?从文档中,我不认为移动/借用适用于引用.



1> Shepmaster..:

至少有两个原因导致不允许这样做:

    你需要有两个并发的可变引用map- 一个由for循环中使用的迭代器保持,一个在变量map中调用map.remove.

    你必须键和值参考范围内试图突变地图时的地图.如果允许您以任何方式修改地图,这些引用可能会失效,从而为内存不安全打开了大门.

核心Rust原则是别名XOR Mutability.您可以对值具有多个不可变引用,或者您可以对其进行单个可变引用.

我不认为移动/借用适用于参考文献.

每种类型都受Rust的移动规则以及可变别名的限制.请让我们知道文档的哪些部分说不是,所以我们可以解决这个问题.

为什么要试图移动参考?

这由两部分组成:

    您只能有一个可变引用

    for循环取值按值迭代

当你打电话时for (k, v) in map {},所有权map转移到for循环,现在已经消失.


我将执行map(&*map)的不可变借用并迭代它.最后,我清楚整个事情:

fn do_it(map: &mut HashMap) {
    for (key, value) in &*map {
        println!("{} / {}", key, value);
    }
    map.clear();
}

使用以字母"A"开头的键删除每个值

我用的是HashMap::retain:

fn do_it(map: &mut HashMap) {
    map.retain(|key, value| {
        println!("{} / {}", key, value);

        !key.starts_with("a")
    })
}

当地图实际被修改时,这保证了key并且value不再存在,因此任何借用它们现在都已经消失了.



2> Peter Hall..:

这在任何语言中都应该是一项微不足道的任务.

你在迭代它时,Rust会阻止你改变地图.在大多数语言中,这是允许的,但通常行为没有明确定义,删除项目可能会干扰迭代,从而影响其正确性.

为什么要试图移动参考?

HashMap实现IntoIterator,所以你的循环相当于:

for (key, value) in map.into_iter() {
    println!("{} / {}", key, value);
    map.remove(key);
}

如果你看一下定义into_iter,你会发现它需要self,而不是&self&mut self.您的变量map是一个引用,因此它被隐式取消引用以获取self,这就是错误说*map已被移动的原因.

有意构建API,以便在循环结构时不会做任何危险.循环完成后,结构的所有权将被放弃,您可以再次使用它.

一种解决方案是跟踪要在a中删除的项目Vec,然后将其删除:

fn do_it(map: &mut HashMap) {
    let mut to_remove = Vec::new();
    for (key, value) in &*map {
        if key.starts_with("A") {
            to_remove.push(key.to_owned());
        }
    }
    for key in to_remove.iter() {
        map.remove(key);
    }
}

您还可以使用迭代器将地图过滤为新地图.也许是这样的:

fn do_it(map: &mut HashMap) {
    *map = map.into_iter().filter_map(|(key, value)| {
        if key.starts_with("A") {
            None
        } else {
            Some((key.to_owned(), value.to_owned()))
        }
    }).collect();
}

但我刚看到Shepmaster的编辑 - 我忘记了retain,哪个更好.它更简洁,不会像我一样做不必要的复制.


推荐阅读
  • 如果您是Java开发人员,您会发现Rust相对容易掌握,这要归功于这两种语言的相似性。technology-most-loved-dreaded-and-wantedclass& ... [详细]
  • 李逍遥寻找仙药的迷阵之旅
    本文讲述了少年李逍遥为了救治婶婶的病情,前往仙灵岛寻找仙药的故事。他需要穿越一个由M×N个方格组成的迷阵,有些方格内有怪物,有些方格是安全的。李逍遥需要避开有怪物的方格,并经过最少的方格,找到仙药。在寻找的过程中,他还会遇到神秘人物。本文提供了一个迷阵样例及李逍遥找到仙药的路线。 ... [详细]
  • rust编程这篇文章是关于我通过解决Twitch上尚未解决的所有CtCI问题来学习Rust的经验。英国科学博物馆集团AdaLovelace的肖像Rust徽标,由Moz ... [详细]
  • SpringBoot uri统一权限管理的实现方法及步骤详解
    本文详细介绍了SpringBoot中实现uri统一权限管理的方法,包括表结构定义、自动统计URI并自动删除脏数据、程序启动加载等步骤。通过该方法可以提高系统的安全性,实现对系统任意接口的权限拦截验证。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 本文介绍了UVALive6575题目Odd and Even Zeroes的解法,使用了数位dp和找规律的方法。阶乘的定义和性质被介绍,并给出了一些例子。其中,部分阶乘的尾零个数为奇数,部分为偶数。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 本文介绍了Codeforces Round #321 (Div. 2)比赛中的问题Kefa and Dishes,通过状压和spfa算法解决了这个问题。给定一个有向图,求在不超过m步的情况下,能获得的最大权值和。点不能重复走。文章详细介绍了问题的题意、解题思路和代码实现。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 一维数组与二维数组互相转换一、二维数组转一维数组1.1使用reduce实现vararr1[[1,2],[3,4],[5,6],[7]];func ... [详细]
  • C++程序员视角下的Rust语言
    自上世纪80年代初问世以来,C就是一门非常重要的系统级编程语言。到目前为止,仍然在很多注重性能、实时性、偏硬件等领域发挥着重要的作用。C和C一样&#x ... [详细]
  • 环境Time2022-04-11Rust1.60.0前言说明基于标准库来学习各种数据结构,并不是从头实现数据结构,未考虑实现性能。特点相比较二叉树,二叉搜索树的左节点都比父节点小, ... [详细]
  • Forexperiencedcryptoinvestors,thereareseveralsectorsthatseemedpromisingbutdidn’tlive ... [详细]
author-avatar
94Wong_386
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有