lpflpf

搬砖程序员带你飞

砖搬得多了,就能盖楼

Rust 编程语言 - 错误处理

两种类型的错误,可恢复的和不可恢复的。

可恢复的用Result<T,E>处理,不可恢复的使用panic!宏处理

处理不可恢复的错误

  • panic 时,默认会回溯调用栈,并打印调用展;若为了将bin文件变小,可以在配置中设置panic = 'abort', 直接终止
  • panic 可以手动调用,也可能是异常触发的(例如数组访问超索引)
  • 一般会保留调用栈,方便问题排查
  • 通过 RUST_BACKTRACE 环境变量打印 调用栈(必须是debug 模式)

处理可恢复的错误

Result 处理可恢复的错误, Result 是枚举类型

Rust 编程语言 - 常见集合

vector 存储列表

  • 类型 Vec
  • 新建 let v: Vec<i32> = Vec::new();
    • 由于推断不出类型,所以需要增加类型注解,强化模版类型
    • vec! 宏初始化
1
2
let mut v = Vec::new() // 可以推断,所以不需要注解
v.push(123) // 推断为123
  • 增加元素 v.push(123);
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
let v = vec![1, 2, 3, 4, 5];

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

let third: Option<&i32> = v.get(2);
match third {
    Some(third) => println!("The third element is {third}"),
    None => println!("There is no third element."),
}
  • 获取元素两种方式
    • 一种 [] 直接取值,索引不存在会panic
    • 一种 get 方法,返回 Option 类型,通过match 判断是否存在;不存在返回None
  • 当数组是可变的,但是借用给一个不可用的变量,则该数组将变得不可用
  • vector 遍历
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// 不可变的访问
let v = vec![100, 32, 57];
for i in &v {
        println!("{i}");
}

// 可变的引用
for i in &mut v {
    *i += 50
        println!("{i}");
}

vector 中存储不同类型

采用枚举类型存储数据. 枚举类型可以标记出最大的存储大小,确保Vec长度是一定的.eg

Rust 编程语言 - 使用包、Crate 和模块管理不断增长的项目

系统模块

  • 包(Packages):Cargo的功能,用于构建测试和分享crate
  • Crates: 一个模块的树形结构,形成库或二进制项目
  • 模块(Modules) 和 use:允许控制作用域和路径的私有行
  • 路径(path): 一个命名,例如结构体、函数或者模块等项的方式

包和crate

包中默认查找两个rs; src/main.rs, src/lib.rs; 确认生成两个crate.(一个二进制,和一个库)

Rust 编程语言 - 枚举和模式匹配

枚举的定义

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 定义 ip 类型
enum IpAddrKind {
    V4,
    V6,
}

// 访问 枚举值 
let four = IpAddrKind::V4;

// 不同成员可以使用不同类型和数量的数据,可以定义为同一种类型
enum IpAddr {
        V4(u8, u8, u8, u8),
        V6(String),
}
let home = IpAddr::V4(127, 0, 0, 1);

let loopback = IpAddr::V6(String::from("::1"));

// 枚举上可以定义方法

impl IpAddr {
    fn call(&self){

    }
}

Option 枚举

  1. 用于判定控制的一种枚举。在标准库中定义。
  2. 使用Option类型值,需要强类型转换
  3. 当使用时,需要显示判断None的情况
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 可以看作是一种枚举类型,包含了None
// 在标准库中的定义形式
enum Option<T> {
    None,
    Some(T),
}

// 使用Option, 变量可为空的值
let absent_number: Option<i32> = None;
let y: Option<i8> = Some(5); 

match 控制流

  1. match 必须是穷尽枚举,没有穷尽会报错
  2. other 对其他的处理
  3. _忽略其他
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter,
}

fn value_in_cents(coin: Coin) -> u8 {
    // 针对不同的场景,做不同处理
    match coin {
        Coin::Penny => {
            println!("Lucy Penny")
            1,
        }
        Coin::Nickel => 5,
        Coin::Dime => 10,
        Coin::Quarter => 25,
    }
}

// match Option
fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
        None => None,
        Some(i) => Some(i + 1),
    }
}

// 穷尽的例子

let dice_roll = 9;
match dice_roll {
    3 => add_fancy_hat(),
    7 => remove_fancy_hat(),
    other => move_player(other), // 通过other 确保穷尽
}

fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn move_player(num_spaces: u8) {}

// 忽略其他

let dice_roll = 9;
match dice_roll {
    3 => add_fancy_hat(),
    7 => remove_fancy_hat(),
    _ => reroll(),
}

fn add_fancy_hat() {}
fn remove_fancy_hat() {}
fn reroll() {}

let if 简单控制流

  1. 通过 let if ,减少 _ 的样板代码;
  2. 虽然代码减少了,但无法做穷尽检查;
1
2
3
4
5
    let config_max = Some(3u8);

    if let Some(max) = config_max {
        println!("The maximum is configured to be {}", max);
    }

Rust 编程语言 - 使用结构体组织相关联的数据

定义

1
2
3
4
5
6
struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}

初始化

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
    let mut user1 = User {
        active: true,
        username: String::from("someusername123"),
        email: String::from("someone@example.com"),
        sign_in_count: 1,
    };

// 字段初始化简写
fn build_user(email: String, username: String) -> User {
    User {
        active: true,
        username,
        email,
        sign_in_count: 1,
    }
}

// user2 中的其他字段从user1中获取
// String 类型的数据被移动,user1 中不能再使用
let user2 = User {
        email: String::from("another@example.com"),
        ..user1 // 必须放最后
};


// 元组结构体 
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

// 类单元结构体,实现 trait
struct AlwaysEqual;

case

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// 标记没有实现
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };
     println!(
        "The area of the rectangle is {} square pixels.",
        area(&rect1)
    );
}

fn area(rectangle: &Rectangle) -> u32{
    rectangle.width * rectangle.height
}

dbg! 可以打印所有权, 重要

0%