《Rust权威指南》学习笔记之第8章 通用集合类型

news/2024/7/3 10:46:50

《Rust权威指南》学习笔记之第8章 通用集合类型

  • 动态数组
    • 创建
    • 更新
    • 销毁
    • 读取动态数组中的元素
    • 遍历
  • 枚举存储多个类型值
  • 字符串存储UTF-8文本
    • 字符串是什么
    • 创建新字符串
  • 更新字符串
  • 字符串索引
    • 内部布局
  • 字符串切片
  • 遍历字符串
  • 哈希映射中存储键值对
    • 创建哈希映射
    • 哈希映射与所有权
    • 访问哈希映射中的值
    • 更新哈希映射
    • 覆盖旧值
    • 只在键无值时插入数据
    • 基于旧值来更新值
    • 哈希函数

集合数据类型,数据存储在堆上,可以增删。

  • 动态数组(vector)可以连续存储任意多个相同类型的值。
  • 字符串(string)是字符的集合。
  • 哈希映射(hash map)值关联到特定键上,映射(map)的特殊实现。

动态数组

Vec<T>

创建

let v: Vec<i32> = Vec::new();

let v = vec![1, 2, 3];

更新

let mut v = Vec::new();
v.push(5);
v.push(6);
v.push(7);
v.push(8);

销毁

{
	let v = vec![1, 2, 3, 4];
}

读取动态数组中的元素

let v = vec![1, 2, 3, 4, 5];

let third: &i32 = &v[2];
println!("The third element is {}", third);

match v.get(2) {
	Some(third) => println!("The third element is {}", third),
	None => println!("There is no third element.", third),
}
let v = vec![1, 2, 3, 4, 5];

let does_not_exist = &v[100];	//panic
let does_not_exist = v.get(100);	//None
let mut v = vec![1, 2, 3, 4, 5];

let first = &v[0];	//不可变引用
v.push(6);	//可变引用
println!("The first element is {}", first);//error

遍历

let v = vec![100, 32, 57];
for i in &v {
	println!("{}", i);
}
let mut v = vec![100, 32, 57];
for i in &mut v {
	*i += 50;;
}

枚举存储多个类型值

enum SpreadsheetCell {
	Int(i32),
	Float(f64),
	Text(String),
}

let row = vec![
	SpreadsheetCell::Int(3),
	SpreadsheetCell::Text(String::from("blue")),
	SpreadsheetCell::Float(10.12),
]

字符串存储UTF-8文本

字符串基于字节的集合,使用UTF-8编码.

字符串是什么

核心部分只有一种字符串类型,字符串切片str,常以借用形式&str出现。
标准库中String,OsString,OsStr, CString, CStr。

创建新字符串

let mut s = String::new();

let data = "initial contents"; //&str
let s = data.to_string();

let s = "initial contents".to_string();
let s = String::from("initial contents");

更新字符串

let mut s1 = String::from("foo");
let s2 = "bat"
s1.push_str(s2);
println!("s2 is {}", s2);

s1.push('1');
let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; //s1已被移动
//fn add(self, s: &str) -> String

编译器可以自动将&String类型的参数强制转换为&str类型,解引用强制转换技术,将&s2转换为了&s2[…]。

let s1 = String::from("tic");
let s2 = String::from("tac");
let s3 = String::from("tce");

//不会夺取任何参数的所有权
let s = format!("{}-{}-{}", s1, s2, s3);

字符串索引

let s1 = String::from("hello");
let h = s1[0]; 	//错误,Rust字符串不支持索引

内部布局

String是基于Vec<u8>的封装类型。
let len = String::from(“Hola”).len(); //4
let len = String::from(“你好”).len(); //?

字节、标量值及字形簇

字符串切片

let s1 = String::from("hello");
let h = &s1[0..4]; 	

遍历字符串

for c in "你好world".chars() {
	println!("{}", c);
}
for b in "你好world".bytes() {
	println!("{}", b);
}

哈希映射中存储键值对

HashMap<K, V>,内部实现中使用了哈希函数。哈希(hash)、映射(map)、对象(object)、哈希表(hash table)、字典(dictionary)、关联数组(associative array)等。所有键相同类型,所有值相同类型。

创建哈希映射

use std::collections::HashMap;

let mut scores = HashMap::new();

scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Yellow"), 50);
use std::collections::HashMap;

let teams = vec![String::from("Blue"), String::from("Yellow")];
let initial_scores = vec![10, 50];

let scores: HashMap<_, _> = teams.iter().zip(initial_scores.iter()).collect();

哈希映射与所有权

实现了Copy trait类型,如i32,值会被简单复制;String这种持有所有权类型,值和所有权会被转移给哈希映射。

use std::collections::HashMap;

let field_name = String::from("Favorite color");
let field_value = String::from("Blue");

let mut map = HashMap::new();
map.insert(field_name, field_value);
//field_name和field_value失效。

引用插入哈希映射,不会被移动。这些引用所指向的值必须要保证,在哈希映射有效时自己也是有效的。

访问哈希映射中的值

use std::collections::HashMap;

fn main() {
    let mut scores = HashMap::new();

    scores.insert(String::from("Blue"), 10);
    scores.insert(String::from("Yellow"), 50);

    let team_name = String::from("Blue");
    let score = scores.get(&team_name);

    match score {
        None => println!("None"),
        Some(i) => println!("{}", i),
    }

    for (key, value) in &scores {
    	println!("{}: {}", key, value);
    }
    println!("Hello, world!");
}

更新哈希映射

覆盖旧值

use std::collections::HashMap;

let mut scores = HashMap::new();

scores.insert(String::from("Blue"), 10);
scores.insert(String::from("Blue"), 25);

println!("{:?}", scores);

只在键无值时插入数据

use std::collections::HashMap;

let mut scores = HashMap::new();

scores.insert(String::from("Blue"), 10);

scores.entry(String::from("Yellow")).or_insert(50);
scores.entry(String::from("Blue")).or_insert(50);

println!("{:?}", scores);

基于旧值来更新值

use std::collections::HashMap;

let text = "hello world wonderful world";

let mut map = HashMap::new();

for word in text.split_whitespace() {
	let count = map.entry(word).or_insert(0);
	*count += 1;
}

println!("{:?}", scores);

哈希函数

为了提供抵御拒绝服务攻击(DoS,Denial of Service)的能力,HashMap使用了默认哈希函数。可以通过实现BuildHasher trait的类型,自定义哈希函数。


http://www.niftyadmin.cn/n/2037902.html

相关文章

进程占用情况记录

使用一下命令查使用内存最多的3个进程 ps -aux | sort -k4nr | head -K 说明&#xff1a; 如果是10个进程&#xff0c;K10&#xff0c;如果是最高的三个&#xff0c;K3 说明&#xff1a;ps -aux中&#xff08;a指代all——所有的进程&#xff0c;u指代userid——执行该进程的用…

《Rust权威指南》学习笔记之第9章 错误处理

《Rust权威指南》学习笔记之第9章 错误处理不可恢复错误与panic!panic!中产生回溯信息可恢复错误与Result匹配不同错误失败时触发panic的快捷方式&#xff1a;unwrap和expect传播错误传播错误的快捷方式&#xff1a;&#xff1f;运算符?运算符只能被用于返回Result的函数要不要…

P2018 消息传递

暴力贪心即可. 考虑从下往上计算. 对于一个根节点的所有子节点, 明显我们应该优先告诉耗时长的子节点. 于是贪心. 假设已经知道了所有子节点的最少花费时间. 我们将其从小到大排序, 那么最后一个应该最先告诉.这可以通过交换法证明. 当前节点的最小花费也就可以构造出来了. #in…

bzoj 1510 [POI2006]Kra-The Disks——思路

题目&#xff1a;https://www.lydsy.com/JudgeOnline/problem.php?id1510 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N3e55,INF1e95; int n,m,h[N],r,p0; int rdn() {int ret0;boo…

C/C++数学运算

C/C数学运算 - * /和数值组成的字符串表达式解析 - * / % ^ ()和数学函数组成的字符串表达式解析最终版字符串计算 - * /和数值组成的字符串表达式解析 #include <iostream> #include <stack> using namespace std;enum TOKEN_TYPE {OPERATOR, NUMBER };//去除exp…

转Jmeter报告优化之New XSL stylesheet

Jmeter默认的报告展示的信息比较少&#xff0c;如果出错了&#xff0c;不是很方便定位问题。由Jmeter默认报告优化这篇文章可知&#xff0c;其实由.jtl格式转换为.html格式的报告过程中&#xff0c;style文件起了很关键的作用。下面介绍另一种style文件的使用方法&#xff1a; …

计算机网络概述 传输层 TCP拥塞控制

TCP拥塞控制 计算机网络中的带宽、交换结点中的缓存和处理机等&#xff0c;都是网络的资源。在某段时间&#xff0c;若对网络中某一资源的需求超过了该资源所能提供的可用部分&#xff0c;网络的性能就会变坏。这种情况就叫做拥塞。 拥塞控制就是防止过多的数据注入网络中&…

PHP登录怎么写安全,PHP登录安全理念

我有一个系统登录用户并验证他们在页面上登录的想法 .我意识到那里有很多系统&#xff0c;但我主要是好奇&#xff0c;如果我的想法是好的 . 我一直认为是重要的做法(如密码加密等) . 我真的使用了应用程序安全性&#xff0c;希望得到一些反馈 .当用户登录时&#xff0c;他们的…