rust 相关知识

目录

参考网址

1. 基本命令

1.1. rustup

# 安装
curl --proto '=https' --tlsv1.3 https://sh.rustup.rs -sSf | sh

# 更新
rustup update

# 卸载
rustup self uninstall

# 编译
rustc main.rs

1.2. cargo

# 创建项目
cargo new project_name
# 库项目
cargo new --lib lib_name

# 构建
cargo build
# 发布构建
cargo build --release

# 运行
cargo run

# 检查
cargo check

# 更新 crate
cargo update

2. 基本知识

2.1. 变量、数据类型

2.1.1. 变量

// 常量, 必须注明类型, 只能是常量表达式
const THREE: u32 = 3 * 3;

pub fn main() {
    let a1 = 1;
    // 可变变量
    let mut a2 = 2;
    // 隐藏前面的声明, 可以改变 数据类型和可变性
    let mut a1 = String::new();
}

2.1.2. 数据类型

  1. 标量类型
    pub fn main() {
        // 整型
        let a: u8 = 1;
        let a: u16 = 1;
        let a: u32 = 1;
        let a: u64 = 1;
        let a: u128 = 1;
    
        let b: i8 = -1;
        let b: i16 = -1;
        let b: i32 = -1;
        let b: i64 = -1;
        let b: i128 = -1;
        // 依赖计算机架构,64位则为64,32位则为32
        let c: isize = -1;
        let c: usize = 1;
    
        // 浮点
        let d: f32 = 1.0;
        let d: f64 = 2.0;
    
        // 布尔
        let e: bool = true;
    
        // 字面量
        let mut f = 0b11;
        f = 0o7;
        f = 0xff;
        f = b'c'; // 单字节字符, 仅限 u8
        f = 10_000;
    
        // 字符, 4个字节, 表示Unicode标量值
        let g: char = '😻';
    }
    
    • 当整型溢出时, 在debug模式下会报错,在 release 下,会进行 二进制补码回绕
  2. 复合类型
    pub fn main() {
        // 元组
        let a: (i32, u32, bool) = (1, 2, true);
        // 元组的解构
        let (x1, x2, x3) = a;
        // 元组的访问
        let a0 = a.0;
    
        // 数组
        let b = [1, 2];
        let b: [i32; 5] = [1, 2, 3, 4, 5];
        let b = [5; 10]; // 重复10个5
                         // 数组的访问
        let b0 = b[0];
    }
    
    • 都是分配在栈空间
    • 都不可改变大小

2.2. 组织代码块(函数、模块)

2.2.1. 函数

fn plus_all(x: i32, y: i32) -> i32 {
    x + y
}

2.2.2. 模块

  1. crate
    • rust 编译的最小单位
    • 有两种形式, 二进制项、库
    • 二进制项有个 main 函数
  2. package (包)
    • 使用 cargo 初始化的就是一个包
    • src/main.rs 为该包下的一个 二进制 crate
    • src/lib.rs 为 crate
    • 上述两种 crate 的名字与 Cargo.toml 中的 name 同名
    • 至少包含一个 crate
    • 至多包含一个 库 crate
    • 位于 src/bin/*.rs 会被认为是多个 二进制 crate
      • 假设有 src/bin/a.rs , src/bin/b.rs 两个文件, 那么运行 cargo build 时,会额外生成 a, b 两个二进制文件
  3. 模块

    规则如下:

    • src/main.rs src/lib.rs 构成 crate 模块 (根模块)
    • 声明模块:
      • 内联, 在同一文件中, 以 mod mod_a {} 方式声明
      • 文件形式,创建 src/mod_a.rs 文件
      • 文件夹形式,创建 src/mode_a/mod.rs 文件
      • 在 crate 中包含 mod mod_a; 告知编译器导入该文件模块
    • 声明子模块:
      • 内联
      • 文件形式,创建 src/mod_a/sub_mod.rs 文件
      • 文件夹形式,创建 src/mod_a/sub_mode/mod.rs 文件
      • 父模块需要包含 mod sub_mod; 来告知编译器导入该子文件模块
    • 声明模块或子模块时,如果同时存在上述几种的模式,那么编译器会报错
    • 使用 use 可以创建成员的快捷方式, 例如 use mod_a::fn_b;

    模块及其成员对父模块默认是私有的, 使用 pub 变成公有

  4. 引用模块
    mod sub {
        pub fn run() {}
        pub mod b {
            pub fn run_b() {
                // 根引用
                crate::mod_a::sub::run();
                // 自引用
                self::bb::run_bb();
                bb::run_bb();
            }
    
            pub mod bb {
                pub fn run_bb() {}
            }
            pub mod bc {
                pub fn run_bc() {
                    // 父级, 类似与 ..
                    super::bb::run_bb();
                }
            }
        }
    }
    

    除了 enum 的成员, 所有成员默认都是私有的

  5. use 的使用
    use std::io;
    
    // 合并 use
    use std::{arch, fmt};
    
    // 重命名
    use std::fmt::Result as FmtResult;
    
    mod mod_b {
        pub mod mod_c {}
    }
    // 导入深层模块, 并导出
    pub use self::mod_b::mod_c;
    
    // 导入全部
    use std::collections::*;
    
    // 使用 self
    use std::collections::{self, HashMap};
    
    fn run() {
        let a: collections::HashSet<i32> = collections::HashSet::new();
    }
    

    惯例:

    • use 函数时, 层级到父模块, 例如: use mod_a; , 使用时 mod_a::fn();
    • use 结构体,枚举等其他项时,层级到具体的项,例如 use std::collections::HashMap;

2.3. 控制语句

2.3.1. 条件语句

fn main() {
    let a = 1;
    let a2 = 1;
    if a > 0 {
        println!("a");
    } else if a2 < 10 {
        println!("cc");
    } else {
        println!("b");
    }

    // 赋值
    let b = if a > 0 { 1 } else { 2 };
}

2.3.2. 循环语句

fn main() {
    // 一般形式
    let mut a = 1;
    loop {
        if a > 4 {
            break;
        }
        a += 1;
    }

    // 终止外层循环
    let mut b = 1;
    'wrap: loop {
        loop {
            b += 1;
            if b > 10 {
                break 'wrap;
            }
        }
    }

    // 获取循环的结果
    let b = loop {
        a += 2;
        if a > 110 {
            break a * 2;
        }
    };

    // while
    let mut a = 1;
    while a < 10 {
        a += 1;
    }

    // for
    let a = [1, 2, 3, 4];
    for item in a {
        println!("item is {item}");
    }
}

2.4. 数据结构

2.4.1. 结构体

  • 基本使用
// 声明
struct User {
    username: String,
    age: u8,
    active: bool,
}

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

// 类单元结构体
struct Always;

fn main() {
    // 实例化
    let u1 = User {
        username: String::from("Mike"),
        age: 10,
        active: false,
    };

    // 依据其他实例更新现有实例
    let mut u2 = User {
        username: String::from("Mary"),
        ..u1
    };

    // 属性 读
    let name = u1.username;
    // 属性 写
    u2.age = 12;

    // 元组结构体实例化
    let color = Color(0, 0, 0);
    println!("{:?}", color.0);

    // 类单元结构体
    let a = Always;
}
  • 进阶

    mod a {
        #[derive(Debug)] // 使得 println! 可以打印
        pub struct User {
            pub username: String,
            age: u8,
            active: bool,
        }
    
        impl User {
            // 方法
            pub fn is_adult(&self) -> bool {
                self.age > 18
            }
            // 关联函数
            pub fn new(username: String, age: u8) -> User {
                User {
                    username,
                    age,
                    active: false,
                }
            }
        }
    
        // 可以有多个实现
        impl User {
            pub fn age(&self) -> u8 {
                self.age
            }
            pub fn bigger(&self, user: &User) -> bool {
                self.age > user.age
            }
        }
    }
    
    use self::a::User;
    
    fn main() {
        // 调用关联函数
        let u1 = User::new(String::from("Mike"), 10);
    
        // 调用方法
        if u1.is_adult() {
            println!("{:?} is adult", u1)
        };
    
        // 只能访问公有字段和方法
        println!("name: {:?}, age: {:?}", u1.username, u1.age());
        println!("user is {:?}", u1);
        dbg!(&u1); // 更详细的 debug 输出
    }
    

2.4.2. 枚举类型

2.5. 异常处理

2.6. 项目管理和构建

3. 标准库

4. 常见应用

4.1. 数学运算

4.2. 字体串处理

4.3. 时间处理

4.4. 网络请求

4.5. 数据库操作

4.6. 访问本地资源

日期: 2022-12-22

Created: 2022-12-25 Sun 19:16

Validate