Rust 学习笔记4
写在前面
这一章主要写的Rust的错误处理还有泛型,Trait,生命周期的知识。
- 感觉异常处理在实际编程中很重要。由于题主是本科生,还没做过啥项目,也没有什么很深的感触,因此,写的比较草率。如果以后还有机会,肯定会补充这个专栏的。
- 泛型是现代语言发展中很重要的一个环节
- 生命周期在Rust中important important important!!!
8.1 Rust错误类型
- 可恢复错误 Result<T,E>
- 不可恢复错误
8.1.1 panic!宏
两种方式:
-
程序展开调用栈
-
立即终止调用栈
-
cargo.toml中声明
[profile.release]
panic = ‘abort’
-
-
设置环境变量RUST_BACKTRACE可以得到panic回溯信息
-
必须带有调试信息 - - release
8.2 Result枚举与可恢复的错误
8.2.1 Result泛型
-
enum Result <T,E>{
Ok(T), //返回成功的时候,返回的是T
Err(E), //返回失败的时候,返回的是E
}
-
可以使用match来进行错误矫正,实现可恢复的作物来进行错误处理
8.2.2 unwrap
- 相当于是match表达式里面的方法,直接调用unwrap方法
8.2.3 expect
- unwrap可以对错误信息进行重新定义(自定义)
8.2.4 传播错误
-
?运算符
let mut f =File::open(”Hello.txt”)?;
成功就继续执行Ok
不成功就返回错误信息Err
-
from函数
将一个错误类型转换为另一个错误类型
?调用的时候会发生隐式调用
-
使用链式调用
把方法连接在一起进行写
8.3 什么时候使用Panic!
- 最终可能处于损坏状态时候,最好使用panic!
- 如果失败是可以预期的使用Rusult
- 可以利用错误处理,来封装一个自定义数据类型检查器
chapter 9 泛型、Trait、生命周期
9.1 提取函数消除重复代码
- 错误率太高
- 识别重复代码
- 提取重复代码
- 得到返回值
9.2 泛型
9.2.1 泛型的作用
- 提高代码复用性
- 具体类型或者其它属性的抽象→编写的其实是一个模板
- fn largest(list: &T)→T{…}
9.2.2 函数定义中的泛型
- 结构体里面使用泛型
struct Point<T,U>{
x:T;
y:U;
}
- 枚举中的泛型
enum Option<T>{
Some(T),
None,
}
enum Option<T,E>{
Ok<T>,
Err(E),
}
9.2.3 方法中使用泛型
impl<T> Point<T>{
fn x(&self) -> &T{
&self.x
}
}
- 只针对具体方法使用泛型
- 结构体中的泛型类型参数可以不一样,因此可以混合调用
9.2.4 泛型使用的性能
- 单态化
- 将泛型转换为具体的类型
9.3 Trait
9.3.1 定义一个Trait
-
trait关键字
-
be like interface
-
一个方法签名占据一行
-
impl trait_name for fn_name{
// 实现trait
}
9.3.2 实现trait的约束
- trait是在本地crate定义的
- 无法实现外部的trait→孤儿规则
- trait抽象实现的方法之间可以相互关联,但是关联的方法必须实现后才能进行调用。
9.3.3 trait作为参数
- impl trait_name
- trait bound 写法
pub fn notify<T:trait_name>(T){}
- 指定多个trait 则可以使用+将多个triat连接起来
→trait 约束信息可以使用where语句,where 写到函数签名的后面,前面直接写参数的名字
9.3.4 trait作为返回类型
- 返回只能返回同一种类型
fn largest<T:PatialOrd + Clone>(list: &[T]) ->T{
let mut largest = list[0].clone();
for item in list.iter(){
if item > &largest{
largest = item.clone();
}
}
largest
}
fn main(){
let str_list = vec![String:from"Hello world",Stirng:from"Good Morning"];
let result = largest(&str_list);
println!("The largest word is {}",result);
}
// 上面的程序如果返回的是T的引用就不需要clone了,因为原来发生了所有权的转移
9.3.5 trait bound使用
9.4 生命周期
- 每个引用 都有自己的生命周期
- 避免悬垂引用
9.4.1 借用检查器
- 被引用的生命周期要长于引用者的生命周期
9.4.2 生命周期标注语法
- 描述多个引用的生命周期
- &‘a i32
- 单个生命周期的标注并没有什么意义
- 泛型生命周期应该放在fn_name<>的括号里面
- 取的是生命周期短的那一个
- 返回引用类型
- struct定义中的生命周期标注
struct struct_name<’a>{
part:&’a str,
}
9.4.3 输入、输出生命周期
9.4.4 生命周期省略的三个规则
- 每个引用类型的参数都有自己的生命周期
- 如果只有一个输入生命周期,那么该生命周期被赋给所有的输出生命周期参数
- 如果有多个输入生命周期,那么&self/&mut self的生命周期会被赋予所有的输出生命周期参数
- 如果不满足前三条生命周期规则,那么需要程序员手动标注生命周期
9.4.5 静态生命周期
- ‘static是一个特殊的生命周期:整个程序的持续时间