导图社区 Rust 入门笔记
Rust 语言的入门笔记图,所有权原则: 值有一个变量,这个变量就是所有者; 一个值同时只能有一个所有者; 所有者离开作用域,值会被删除。
编辑于2023-05-25 17:35:37Rust
语法
判断
if
特性
可以有返回值
不以 ; 结尾的表达式 视为返回
每个分支返回类型一致
判断表达式 无括号
循环
形态
for in
for 元素 in 集合
for item in IntoIterator::into_iter(collection)
如果集合不使用引用 for循环过后则无法使用此集合 因为发生了所有权转换 元素实现copy特征的直接拷贝 不会转移所有权
for 元素 in &集合
for item in collection.iter()
不可变借用
for 元素 in &mut 集合
for item in collection.iter_mut()
需要修改此集合 需要添加&mut
while
以判断条件结果为true时继续循环
loop
无限循环
需要 break 跳出
break 可以返回一个值,类似 return
loop是表达式 可以有返回值
控制
continue
跳过此次,开始下次
break
跳出整个循环
range [..]
起始默认为0
结束默认最后一位字符
指定结束索引时
[0..3] 包含 0,1,2 元素
可以使用 = 符号包含当前索引 [1..=3] 包含 1,2,3 下标元素
引用完整切片 [..]
暂时先归到循环中
模式匹配
用以匹配枚举
match 匹配
形态
match target { 模式1 => 表达式1, 模式2 => { 语句1; 语句2; 表达式2 }, _ => 表达式3 }
模式表达式可以使用: X|Y 或
_ 作为最后的默认匹配
有返回值
模式绑定
某个枚举值类型带有值
enum People { Men{ age: u8 }, Women{ age: u8 }, }
匹配时可以把值绑定到一个变量中
match people { People::Men { age } => age, People::Women { age } => age, };
if let 匹配
匹配一项
let ss = Some(31_u8); if let Some(x) = ss { println!("匹配成功,值:{}", x); }
matches! 宏
判断某个值类型是否属于枚举值
let three = Some(3); matches!(three, Some(3)) // true
数据类型
基本数据类型 实现Copy特征
数值类型
字符
布尔
单元类型:() 函数空返回
复合数据类型
字符串
字面值
let s = "字符";
不可变
被硬编码到程序代码中
String类型
动态,存储在堆内存中
切片 slice
引用集合中部分元素序列
元组:( type, type, 等)
固定长度、顺序
可解构
可用下标访问元素
x.下标
常用于函数返回后解构
结构体 struct
创建
提前创建类型
再创建实例
每个字段都需要初始化
顺序可以不一致
更新
可使用 ..xx 进行解构给另一个新的结构体实例
let user2 = User { ..user1 };
必须在尾部使用,起到补充作用
未实现Copy特征的字段所有权被转移后 此字段不可再使用,其他字段则可以继续使用
形态
元组结构体
struct Color(i32, i32, i32); let red = Color(255, 0, 0)
字段可以匿名
单元结构体
struct Foo; let bar = Foo;
空结构体 无字段
所有权
不使用生命周期,则所有字段必须对其值拥有所有权, 不可以引用其他值。
枚举
定义
枚举:是种包含所有可能值的类型
枚举值:是枚举类型中某一个选项的实例
操作
操作符 ::
形态
含值枚举值
enum Message { Quit, Move { x: i32, y: i32 }, Write(String), ChangeColor(i32, i32, i32), } fn main() { let m1 = Message::Quit; let m2 = Message::Move{x:1,y:1}; let m3 = Message::ChangeColor(255,255,0); }
Option 枚举
通过 prelude 内置了 Option 的枚举
enum Option<T> { Some(T), None, }
使用模式匹配解开Option
数组 array
特性
长度固定
元素类型相同
依次线性排列
禁止越界访问
创建
let ls = [ 1, 2, 3, 4, 5 ]
推断
let ls: [u8; 3] = [ 34, 11, 23 ]
类型签名
let ls = [ 8; 5 ]
相同的元素重复x次
访问
ls[0]
下标访问
数组切片
let a: [i32; 5] = [1, 2, 3, 4, 5]; let slice: &[i32] = &a[1..3];
只是数组的部分数据的引用,代价很小
长度不固定
切片的类型[T]不固定大小,但切片引用&[T]固定大小
需要注意
类型签名
数组 [ T; n ]
数组切片 [ T ]
数组切片的引用 &[ T ]
长度也是数组类型的一部分
[u8; 2] 和 [u8; 1] 是不同类型
所有权
栈 stack 后进先出
空间大小固定
堆 heap 先进先出
不确定大小,内存不够用的时候需要换地方。所以需要指针指向。
指针进栈
原则
值有一个变量,这个变量就是所有者
一个值同时只能有一个所有者
所有者离开作用域,值会被删除
引用
&符号 指针借用
解引用
*xx
可变引用
作用域内 只存在一个
两个以上的指针同时访问统一数据
至少有一个指针用来修改数据
没有同步数据访问的机制
不可变引用
必须总是有效,不可存在悬垂引用
拷贝
实现Copy特性的类型,会浅拷贝 不会转移所有权,而是创建一个新的变量
基本数据类型
整数 例如:u8
浮点数 例如:f64
布尔 bool
不需要分配堆内存的类型
所有元素都是已经实现Copy特性的元组 例如:(u8, bool, f32, i16)
不可变引用 例如:&T
打印
dbg! 宏
拿走所有权,最后返回
抽象表达
泛型
通过定义泛型参数,对类型进行抽象
使用
结构体中
struct Point<T> { x: T, y: T, }
枚举中
enum Option<T> { Some(T), None, }
enum Result<T, E> { Ok(T), Err(E), }
方法中
示例
struct Point<T, U> { x: T, y: U, } impl<T, U> Point<T, U> { fn mixup<V, W>(self, other: Point<V, W>) -> Point<T, W> { Point { x: self.x, y: other.y, } } } fn main() { let p1 = Point { x: 5, y: 10.4 }; let p2 = Point { x: "Hello", y: 'c'}; let p3 = p1.mixup(p2); println!("p3.x = {}, p3.y = {}", p3.x, p3.y); }
impl<T, U> impl中声明的泛型才是内部使用的泛型,结构体中的泛型名称只是代表结构体是 Point<T> 而不是 Point,是用来标识结构体的。
V W ,是方法中使用的泛型
const 泛型