Home avatar

搬砖程序员带你飞

砖搬得多了,就能盖楼

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! 可以打印所有权, 重要

Rust 编程语言 - 常见编程概念

阅读Rust程序设计语言笔记

变量和可变性

  1. 变量默认是不可改变的(immutable)
  2. 可变变量,需要加 mut 修饰 let mut x = 5
  3. 常量 使用 const 定义
    1. const THREE_HOURS_IN_SECONDS: u32 = 60 * 60 * 3;
    2. 需要申明常量类型
    3. 常量只能被设置为常量表达式,不能是运行时计算出的值 (和变量区别)
  4. 隐藏,变量遮蔽。重新申明变量,前面申明的变量会隐藏
    1. 隐藏时,可以改变变量类型

数据类型

  1. 指定数据类型,或者可以推断出数据类型;
  2. 标量类型:整型,浮点型,布尔型,字符型
  3. 整形
    1. 有符号,无符号
    2. 8,16,32,64,128,arch 几种长度
    3. 支持下划线分隔符
    4. 整形溢出,debug 会panic;release 会忽略高位
    5. 数字可以加后缀 123u16 16位的数字 123
  4. 浮点型
    1. f32,f64;
    2. IEE-754
  5. 数值运算
    1. 整数除法,四舍五入
  6. bool true|false
  7. 字符类型
    1. 四个字节,一个Unicode标量
  8. 复合类型
    1. 元组
      1. 申明后长度不会增大缩小;类型不必相同
      2. 通过模式匹配解构(destructuring)元组值
      3. 通过(.) 加索引访问
      4. let x: (i32, i64, f32) = (100, 0, .3)
    2. 数组
      1. 长度固定;类型必须相同;
      2. 不固定长度,需要使用vector 类型(标准库提供)
      3. let a = [1,2,3,4,5]
      4. let a: [i32; 5] = [1,2,3,4,5]; 指定类型
      5. let a = [3;5] 创建5个3
      6. 访问超出界限,会panic

函数

  1. 加分号是语句,不加分号是表达式(又返回值)
1
2
3
4
5
6
7
8
fn a_func(x: i32){
   println!("hello world");
}

// 返回值类型是i32,返回数据是5
fn five() -> i32 {
   5
}

注释

  1. // 注释
  2. /// 文档注释

控制流

  1. if 语句
  2. 条件不用加括号
  3. 必须bool类型,不能自动转换
  4. 可以使用let语句赋值
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// if 不用加括号
// 必须是bool类型,不会自动转换
if number < 5 {
   println!("")
}else if number % 3 == 0 {
   println!("")
}else {
   println!("")
}

// if else 返回类型必须相同
let number = if condition {5} else {6};
  1. 循环 (loop while/for)
  2. break 中断; 可以带返回值中断
1
2
3
4
5
6
7
let result = loop {
   counter += 1;

   if counter == 10 {
      break counter * 2; // result 赋值为20
   }
}
  1. 多个循环之间消除歧义

标签 ‘counting_up (这个好诡异)

0%