rust 初探 -- 常用的集合

embedded/2024/9/22 15:03:18/

rust____0">rust 初探 – 常用的集合

Vector

存储在堆内存上的数据,运行时可以动态变大或者变小。
Vec 特性:

  • 由标准库提供,可以存储多个相同类型的值,并且值在内存中连续存放

Vector 的创建

rust">fn main() {// Vec::new()let v: Vec<i32> = Vec::new();// 使用初始值创建,使用 vec! 宏let v1 = vec![1,2,3];
}

更新 Vector

rust">fn main() {//这里不需要指明 vec 的类型,因为后面有 push 操作会自己推断出来let mut v = Vec::new();v.push(1);
}

删除 Vector

和其他的 struct 结构体一样,当 Vector 离开了作用域,就会被清理掉
如果涉及到引用会不一样。

读取 Vector 的元素

rust">fn main() {let v = vec![1,2,3,4,5];let third = &v[2]; // 1. 使用索引,非法访问 panicprintln!("{}", third);match v.get(2) { // 2. get 方法,非法访问 返回 NoneSome(third) => println!("get {}", third),None => println!("not exist"),}
}
所有权和借用规则

不能在同一作用域里,对一个值不能同时有可变和不可变的引用

rust">//vec 中内存中是连续的,新增的时候可能会重新分配,所以直接不让这样操作
fn main() {let mut v = vec![1,2,3,4,5];let third = &v[2]; //不可变的v.push(6); //mutable borrow occurs hereprintln!("{}", third);
}
遍历 Vector 的值
rust">fn main() {let mut v = vec![1,2,3,4,5];for i in &mut v {*i += 50;}for i in v {println!("{}", i);}
}
使用 enum 来存储多种数据类型
  • enum 的变体可以附加不同类型的数据
  • enum 的变体定义在同一个 enum 类型下
rust">enum Cell {Int(i32),Float(f64),Text(String),
}
// 因为类型不同,枚举的时候不好操作(很多个),需要使用到 trait 对象
fn main() {//编译时就知道堆上要多大的内存,而且知道所有的可能情况,编译时可以做检查let row = vec![Cell::Int(3),Cell::Float(10.1),Cell::Text(String::from("text")),];
}

字符串是什么

  • Rust 的核心语言层面,只有一个字符串类型:字符串切片 str(或&str)

  • 字符串切片:对存储在其他地方、UTF-8编码的字符串的引用

    • 字符串字面值:存储在二进制文件中,也是字符串切片
  • String 类型:

    • 来自标准库而不是核心语言
    • 可增长、可修改、可拥有

通常说的字符串是指?

String 和 &str

  • 特性:utf-8 编码

其他类型的字符串

  • OsString,OsStr,CString,Cstr
  • 还有一些其他第三方库

创建一个新的字符串

rust">String::new()//用于创建一个空的字符串,是可变的
to_string()	//方法,可用于实现了 displag trait 的类型,包括字符串字面值
String::from() //函数,从字面值来创建字符串

更新 String

  • push_str() 方法:字符串切片
rust">fn main() {let mut s1 = String::from("foo");s1.push_str("bar");//- push_str() 方法:字符串切片println!("{}", s1); // foobars1.push('b');//- push() 方法:单个字符println!("{}", s1); // foobarb
}
    • 操作符,拼接字符串
rust">fn main() {let s1 = String::from("foo");let s2: String = String::from("bar");let s3 = s1 + &s2;//相当于 fn add(self, s: &str) -> String {}//&String 强制转换成 &str,解引用强制转换(deref coercion),会保留 s2 的所有权println!("{}", s3);// println!("{}", s1);//error[E0382]: borrow of moved value: `s1`// println!("{}", s2);
}
  • format!:不会取得任意参数的所有权
rust">use std::fmt::format;fn main() {let s1 = String::from("foo");let s2: String = String::from("bar");let s3: String = String::from("car");// let s4 = s1 + "-" + &s2 + "-" + &s3;// println!("{}", s4); //foo-bar-carlet s5 = format!("{}-{}-{}", s1, s2, s3);println!("{}", s5);//foo-bar-car
}

内部表示

  • String 是对 Vex 的包装
rust"> String::from("hola").len(); //4,返回字节数// unicode 标量值
字节,标量值,字形簇
rust">fn main() {let w = "测试一下";for b in w.bytes() {//字节print!("{} ", b)//230 181 139 232 175 149 228 184 128 228 184 139 }for b in w.chars() {//标量值print!("{} ", b)// 测 试 一 下}
}
访问 String
  • 不支持按索引语法形式进行访问:
    • 不同语言的字符串,其对应的字节数不同
    • 索引操作应消耗一个常量时间(O(1)),而String 无法保证,需要遍历所有内容来确定有多少个合法的字符
切割 String
rust">s = &hello[0..4]; //但是切割必须沿着字符的边界切割,否则会panic

HashMap<K, V>

  • 键值对的形式存储数据
  • 适合场景,通过 K (任何类型)来寻找数据,而不是通过索引

创建 HashMap

rust">use std::collections::HashMap;fn main() {//创建 HashMaplet mut scores = HashMap::new();scores.insert(String::from("bob"), 99); //会基于此推断 k,v的类型// 不在 Prelude 中,所以需要添加 use //2. collect()let team = vec![String::from("a"), String::from("b")];let t_scores = vec![10,12];let hp: HashMap<_, _> = team.iter().zip(t_scores.iter()).collect();// 需要指明 HashMap<_, _>
}
  • 数据存储在 heap 上
  • 同构的:一个 HashMap 中,所有 k 必须是同一类型,所有 v 必须是同一类型

HashMap 和所有权

  • 对于实现了 Copy trait 的类型,值会被复制到 HashMap 中
  • 对于拥有所有权的值(如 String),值会被移动,所有权会被转移给 HashMap
  • 如果将值的引用插入到 HashMap,值本身不会移动 (被引用的值需要有效)
rust">fn main() {let name = String::from("key");let value = String::from("value");//创建 HashMaplet mut scores = HashMap::new();// scores.insert(name, value);// print!("{}:{}", name, value); // value borrowed here after movescores.insert(&name, &value);println!("{}:{}", name, value);//key:value
}

访问 HashMap

  • get 方法,参数 K,返回 Option<&V>
rust">use std::collections::HashMap;fn main() {//创建 HashMaplet mut scores = HashMap::new();scores.insert(String::from("bob"), 90);scores.insert(String::from("lili"), 100);let name = String::from("bob");let score = scores.get(&name);match score {Some(s) => println!("{}", s), // 90None => println!("team not exist"),};
} 

遍历 HashMap

rust">use std::collections::HashMap;fn main() {//创建 HashMaplet mut scores = HashMap::new();scores.insert(String::from("bob"), 90);scores.insert(String::from("lili"), 100);for (k, v) in &scores {println!("{}-{}", k, v)//lili-100 bob-90}
}

更新 HashMap

  • HashMap 大小可变,每个 K 只能对应一个 V
  • 更新 HashMap 中的数据,已存在 K,或者不存在 K
rust">use std::collections::HashMap;fn main() {//创建 HashMaplet mut scores = HashMap::new();scores.insert(String::from("bob"), 90);scores.insert(String::from("lili"), 100);//1. 替换现有的 v,插入两个相同k,不同 v,前者会被后者替换//2. 只在 K 不存在时,才插入 v//使用 entry 方法,结合 or_insert scores.entry(String::from("bob")).or_insert(80);scores.entry(String::from("bob2")).or_insert(80);println!("{:#?}", scores)
}

http://www.ppmy.cn/embedded/90721.html

相关文章

Java中等题-最长回文子串(力扣)

给你一个字符串 s&#xff0c;找到 s 中最长的 回文子串。 示例1&#xff1a; 输入&#xff1a;s "babad" 输出&#xff1a;"bab" 解释&#xff1a;"aba" 同样是符合题意的答案。示例 2&#xff1a; 输入&#xff1a;s "cbbd" 输…

redis面试(三)Hash数据结构

HASH 哈希&#xff0c;在redis底层实现的时候&#xff0c;数据的结构叫做dict 这个Dict就是一个用于维护key和value映射关系的数据结构&#xff0c;与很多语言中的Map类型相似。 本质上也是一个数组链表的形式存在&#xff0c;不同的点在于&#xff0c;每个dict中是可以存在…

机械拆装-基于Unity-本地数据持久化

目录 1. 数据结构简介&#xff1a;数据的集合 1.1 线性数据结构 1.2 非线性数据结构 2. 对数据集合的操作&#xff1a; 3. 数据持久化 3.1 数据的序列化存储 3.2 JSON文件硬盘存储 3.2.1 Json文件允许存储的数据类型 3.2.2 Json文件的语法格式 3.2.3 Json文件的读取 3.2…

手撕算法题4(附思路和源码)

算法 1.单值二叉树2.相同的树3.另一棵树的子树4.二叉树的前序遍历5.二叉树的中序遍历6.二叉树的后序遍历7.二叉树遍历8.TopK问题 1.单值二叉树 单值二叉树 思路 比较父节点和子结点&#xff0c;相同返回true&#xff0c;否则返回false&#xff0c;递归 设计程序 若结点为空返回…

大模型学习笔记 - 大纲

LLM 大纲 LLM 大纲 1. LLM 模型架构 LLM 技术细节 - 注意力机制LLM 技术细节 - 位置编码 2. LLM 预训练3. LLM 指令微调 LLM 高效微调技术 4. LLM 人类对齐 LLM InstructGPTLLM PPO算法LLM DPO 算法 5. LLM 解码与部署6. LLM 模型LLaMA 系列7. LLM RAG 1. LLM 模型架构 大模…

二维码生成原理及解码原理

☝☝☝二维码配图 二维码 二维码&#xff08;Quick Response Code&#xff0c;简称QR码&#xff09;是一种广泛使用的二维条形码技术&#xff0c;由日本公司Denso Wave在1994年开发。二维码能有效地存储和传递信息&#xff0c;广泛应用于商品追溯、支付、广告等多个领域。二维…

设计模式15-门面模式

设计模式15-门面模式 "接口隔离"模式典型模式1. 适配器模式&#xff08;Adapter Pattern&#xff09;2. 装饰模式&#xff08;Decorator Pattern&#xff09;3. 桥接模式&#xff08;Bridge Pattern&#xff09;4. 代理模式&#xff08;Proxy Pattern&#xff09;5. …

【组合数学】【Python】【小练习】一、斯特灵近似式求阶乘

一、问题介绍 斯特灵&#xff08;Stirling&#xff09;近似式&#xff0c;是数学分析中&#xff0c;用于求阶乘近似值的一个常用公式&#xff0c;其简单的表述形式为&#xff1a; 二、Python实现 使用Python&#xff0c;循环从n1至n98&#xff0c;分别输出n的阶乘值、斯特灵公…