首页 > 其他分享 >rust学习九.3-集合之哈希映射表

rust学习九.3-集合之哈希映射表

时间:2024-11-18 18:41:12浏览次数:1  
标签:insert String 映射 哈希 scores println rust

这里介绍的哈希映射表(HashMap)并非是java那样的万用表,限制很大。

不过,话说回来,rust应该是有类似java那样的映射表,不过不是这个哈希映射表。现在先谈论哈希映射表吧。

 

一、构成和定义

HashMap 是最不常用的,所以并没有被 prelude 自动引用。标准库中对 HashMap 的支持也相对较少,例如,并没有内建的构建宏。

必须在代码前use下:

use std::collections::HashMap;

通过有关工具,我们知道哈希映射表内部代码是这样的:

 

和其它语言相比,没有什么特别的,显著的不同,都是包含数组(类似数组之类的)、属性、一些公共的方法。

 

rust的哈希映射表具有许许多多的的方法/属性,例如:

 

 

以上只是部分。

可见,rust的创建者们还是挺费心的,并保持了他们的一贯风格:为开发者们提供了有点尽善尽美的各种实现。

java的实现某种程度看起来更加得简洁。

rust提供了那么多的实现,部分原因也是因为它独有复杂的所有转问题导致的,rust力图让程序员不要在写代码的时候想着哈希表的值所有权的问题

 

二、基本操作

事实上,如前文所言,rust为哈希映射表提供了居多的方法,所以这里有仅仅是列出比较常用的一些,又或者就是作者例文中给出的。

插入

insert

很重要的一点:键类型必须一致,值类型必须一致,否则会报错:

一个很贴心的提示: expected &str ,found Vec...

如果硬要插入不同的,也是间接的,例如插入Option类的值,但那样让一个值变得复杂了。

 

 

访问单个成员

get(&o)

get_mut(&o)

还有许多。

注意,rust的创建者们很喜欢使用Option来包装返回值。也许Option应该改名为万用塑料袋。

 

删除

remove

修改

键是不可修改的,只能修改值。所以所谓的修改就是覆盖值,这个和java等语言的操作是一样的,插入相同的键及其值会自然覆盖已有的,从而达到修改值得目的。

简单一点,就是再次insert

打印

如果是简单得,那么println!("{:?}",xxx),或者再稍微复杂一些: println!("{:#?}",xxx).

遍历

有常见的集中方式:

遍历键集合、便利值集合、迭代器、  (K,V) IN ()

其它

清空.-clear

 

三、所有权

即:创建一个变量v,然后作为一个值放入哈希表,那么v值的所有权归归于谁?

凡是复杂的类型(或者说复合类型)都有这样的问题。 我们只需要记住几个基本点即可。

根据第四章的重要规则:

  1. 一个值(不是变量)一定要有所有者
  2. 而且任意时刻,一个值只能有一个所有者
  3. 值所有者离开作用域后,持有的值会被立刻释放

如果不做特殊处理,所有权就会发生转移-这是毋庸置疑的。

所以,insert之后,原来的值得所有权会发生转移...

当然,如果你的键或者值属于栈类型的,就不会有这个问题,因为所有权这个事情从来都属于堆类型。

 

四、示例

 

/**
 * map 也就是大部分语言中具有的类型,中文称为映射表
 * 内部的实现并没有什么本质的区别:一个数组或者类似数组的东西,加上一堆方法。
 * 根据具体的情况,可以细分为许多子类型的映射表,就好像java那样
 * 
 * 一、哈希映射表的定义/创建
 *    1.所有键的类型必须一致,所有值的类型必须是一致,这和java是大不一样的。  rust应该也有和java对应的,但应该不是哈希映射表
 * 
 * 二、映射表的基本操作
 * 
 * 三、映射表的一些特殊操作
 * 
 * 四、映射表的一些特殊操作
 * 
 * 五、映射表的小结
 * 
 */
use std::collections::HashMap;
use std::any::type_name;
fn print_type_of<T>(_: &T) {
    println!("The type is: {}", type_name::<T>());
}
fn main(){

    let mut family=HashMap::new();
    family.insert(String::from("父亲"),"lzf");
    family.insert(String::from("母亲"),"hxl");
    family.insert(String::from("女儿"),"lml");
    family.insert(String::from("男儿"),"lql");

    println!("{:?}",&family);

    let mut  sun=Vec::new();sun.push("阿大");sun.push("阿二");
    //family.insert(String::from("孙辈"),sun);  //这样是会报错的
    //println!("{:?}",&family);
    println!("{:#?}",&family); //更好的格式

    let mut scores=HashMap::new();
    let g_bad:String=String::from("差");
    let g_mid:String=String::from("中");
    let g_good:String=String::from("良");
    let g_excellent:String=String::from("优");
    let g_perfect:String=String::from("完美");

    scores.insert(String::from("101"),g_bad);   //g_bad被夺取所有权了
    scores.insert(String::from("102"),g_mid);
    scores.insert(String::from("103"),g_excellent);
    scores.insert(String::from("104"),g_good);
    scores.insert(String::from("105"),g_perfect);
    println!("{:#?}",&scores);

    println!("get方法会返回一个不可修改的对象");
    let s103=scores.get("103"); //返回的是一个Option
    println!("103的成绩:{}",s103.unwrap());
    //s103=Some(&String::from("说不清"));  // 这是不可修改,会报错
    let s106=scores.get("106"); //访问一个不存在,会返回None
    println!("106的成绩:{}",s106.unwrap_or(&String::from("不存在")));

    let  mut_s104=scores.get_mut("104");
    print_type_of(&mut_s104);
    println!("现在104的成绩:{}",mut_s104.unwrap());
    
    //println!("{}",g_bad); //g_bad被夺取所有权了,所以这里会报错的    
    print_hm_use_forkv(&scores);
    print_hm_use_forvalues(&scores);
}

fn print_hm_use_forkv(hm:&HashMap<String,String>){
    for (k,v) in hm{
        println!("{}:{}",k,v);
    }
}

fn print_hm_use_forvalues(hm:&HashMap<String,String>){
    for value in hm.values() {
        println!("{}",value);
    }
}

 

五、小结

  1. 虽然和大部分语言类似,但是还是有不小局限性。用起来不是那么友好。这都是拜所有权所赐
  2. 整体上,还是比较方便。但需要特别注意所有权问题
  3. rust提供了足够丰富的函数来处理各种需要

标签:insert,String,映射,哈希,scores,println,rust
From: https://www.cnblogs.com/lzfhope/p/18549706

相关文章

  • rust学习九.2、集合之字符
    按照作者的意思,字符不是看起来那么简单!的确,字符在大部分语言中,都不是看起来那么简单!字符的内容看起来很多,又很少!多是因为涉及到编码、构成、方法(有许多方法)还有字符切片。少是因为,其实和java等语言其实没有大的区别。一、构成rust的字符内部是vec(u8)+方法,看起来和java其实......
  • 代码随想录算法训练营第六天|哈希表|LC242. 有效的字母异位词|LC349. 两个数组的交集|
    哈希表    哈希表:用来快速判断一个元素是否出现在集合里;O(1);    哈希碰撞:比如小王和小李都映射到索引下表1的位置,有2中解决办法(拉链法和线性探测法);    拉链发:通过索引找到,其实拉链发就是要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内......
  • 【小记】如何将多媒体键映射为锁屏
    工作电脑为一体机。所有的USB接口都在屏幕的后面。插拔U盘极不方便。于是搜索USB小物件,看能不能通过小物件将USB的接口延长到屏幕前寻觅一番,找到一个中意的小物件——ELEKSMAKER极客桌面控制器 如上图所示,小物件有着朋克风,充满现代感。带有3个USB2.0接口,日常工作使用足够。......
  • 猫映射(Arnold变换),猫脸变换介绍与基于例题脚本的爆破
    前置信息http://www.jiamisoft.com/blog/index.php/7249-erzhituxiangjiamisuanfaarnold.htmlhttps://mp.weixin.qq.com/s/IbkAlyAPvbgMeNgqfwisTgArnold变换Arnold变换是V.J.Arnold在遍历理论的研究中提出的一种变换,原意为catmapping,俗称猫脸变换。Arnold变换直观、简单、具有......
  • mac 键盘映射软件 karabiner设置
    首先设置为和内置键盘一样的行文然后吧cap键映射为fn最后把fn+hjkl映射为上下左右以下是具体的映射代码:{"description":"Changefn+hjkltoarrowkeys","manipulators":[{"from":{"key_code":"h......
  • 穿越数据迷宫:C++哈希表的奇幻旅程
    文章目录前言......
  • (LeetCode 热题 100) 49. 字母异位词分组(哈希表、字符串)
    题目:49.字母异位词分组思路:哈希表。将每个字符串升序排序,然后采用哈希表即可。C++版本:classSolution{public:vector<vector<string>>groupAnagrams(vector<string>&strs){ //哈希表unordered_map<string,vector<string>>mp;//遍历......
  • RocketMQ负载均衡-消费者的负载均衡-统一哈希算法
    RocketMQ消费者的负载均衡-一致性哈希算法简介在分布式系统中,负载均衡是确保系统高效、可靠运行的关键。RocketMQ作为一款高性能的分布式消息中间件,通过多种负载均衡策略,实现消息队列在多个消费者之间的合理分配。其中,一致性哈希算法(ConsistentHashing)是一种先进的负......
  • 精通rust宏系列教程-入门篇
    Rust最令人敬畏和强大的特性之一是它使用和创建宏的能力。不幸的是,用于创建宏的语法可能相当令人生畏,并且对于新开发人员来说,这些示例可能会令人不知所措。我向你保证Rust宏非常容易理解,本文将为你介绍如何创建自己的宏。什么是Rust宏?println!("hello{}",name)如果......
  • rust逆向初探
    rust逆向葵花宝典rust逆向技巧rust逆向三板斧:[!NOTE]快速定位关键函数(真正的main函数):观察输出、输入,字符串搜索,断点等方法。定位关键加密区:根据输入的flag,打硬件断点,快速捕获程序中对flag访问的位置(加密区)。定位错误输出(附近一定有比较功能的程序):定位到比较位置......