Post

Rust 学习

Rust 学习

介绍

WIP…

Rust、Julia、Fortran 没有类的概念


参考资料


Rust 练习:



使用

Rust 环境安装

1
2
3
4
5
6
7
8
9
10
11
12
13
# 方式 1
brew install rust       # macOS

# 方式 2
curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh

rustup self uninstall   # 卸载

# 加速安装:将 Rust 安装源设置国内源
export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static

# 方式 3
curl -sS https://webi.sh/rustlang | sh
1
2
# 运行简单脚本
rustc *.rs

Cargo

cargo 相关命令

1
2
3
4
5
6
7
8
9
10
11
12
13
cargo --list   # 查看所有安装的命令
# 安装 package (指 Rust binary)
cargo install <package>
# 若有新版本,覆盖旧版本
cargo install <package> --force
# --locked 确保安装时依赖项的版本与在 Cargo.lock 文件中的版本完全一致
cargo install --locked <package>
# 列出所有安装的 packages 及对应的版本
cargo install --list

cargo add <lib>

rustup update  # 更新 Rust 工具链

修改 Rust 的下载镜像为国内的镜像地址:创建或编辑 $HOME/.cargo/config.toml

1
2
3
4
5
6
7
8
9
10
[source.crates-io]
replace-with = 'mirror'

[source.mirror]
# 清华源
registry = "sparse+https://mirrors.tuna.tsinghua.edu.cn/crates.io-index/"
# 科大源
# registry = "sparse+https://mirrors.ustc.edu.cn/crates.io-index/"
# git 写法
# registry = "sparse+git://mirrors.ustc.edu.cn/crates.io-index/"

项目:

1
2
3
4
5
6
7
8
9
10
11
# 创建项目
cargo new <project>

# 运行项目
cargo run     # cargo r;默认使用调试模式编译
cargo run -- arg1 arg2  # 将参数参数传递给程序,用 -- 隔开
cargo run --release  # 使用发布模式编译(优化更好,但编译速度较慢)


# 代码验证
cargo check

cargo run 相当于运行了编译 cargo build 和运行 ./target/debug/XXX 两个步骤

默认是 debug 模式,代码编译速度快,运行速度慢;提高代码性能:添加 --release 编译

1
2
cargo run --release
cargo build --release

项目结构

1
2
3
4
5
├── .git
├── .gitignore
├── Cargo.toml
└── src
    └── main.rs

Cargo.toml:项目数据描述文件

Cargo.lock:项目依赖详细清单

若项目是一个可运行的程序时,可上传 Cargo.lock;若是一个依赖库项目,建议将其添加到 .gitignore 中

Cargo.toml 设置

1
2
3
4
5
6
7
8
9
10
11
12
# package 配置
[package]
name = "world_hello"
version = "0.1.0"
edition = "2021"

# 项目依赖
[dependencies]
rand = "0.3"
hammer = { version = "0.5.0"}
color = { git = "https://github.com/bjz/color-rs" }
geometry = { path = "crates/geometry" }

项目依赖


工具

  • Rust 相关 VSCode 插件:rust-analyzer

  • cargo-update:检查和更新 package 的 cargo 子命令

1
2
3
4
cargo install cargo-update  # 安装

cargo install-update -l     # 列出所有安装的 packages 
cargo install-update -a     # 检查并更新所有安装的 packages 
  • cargo-cache:cargo 缓存管理工具
1
2
3
4
cargo install cargo-cache  # 安装

cargo cache                # 清理缓存
cargo cache -n             # 不实际运行
  • rust-binstall
1
2
3
4
# 安装
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash

cargo binstall ripgrep
1
2
3
brew install topgrade  # 安装
topgrade               # 使用
topgrade -n            # 不实际运行

语法

变量

1
2
3
4
5
6
7
8
let x = 5;
// 变量可变
let mut x = 5;
// 使用下划线开头忽略未使用的变量
let _x = 5;

// 常量
const

若创建了一个变量却不在任何地方使用它,Rust 通常会给你一个警告,因为这可能会是个 BUG


基本类型

Rust 编译器可以根据变量的值和上下文中的使用方式来自动推导出变量的类型

image.png

image.png

浮点类型:f32 和 f64,默认浮点类型是 f64

image.png

NaN 类型

序列:1..5,生成从 1 到 4 的连续数字,不包含 5 ;1..=5,生成从 1 到 5 的连续数字,包含 5

1
2
3
for i in 1..=5 {
    println!("{}",i);
}

字符 '',字符串 ""

单元类型:()

main 函数就返回单元类型

没有返回值的函数在 Rust 中有单独定义

1
2
3
4
5
// 类型注释
fn add(i: i32, j: i32) -> i32 {
   i + j
 }

语句:加分号 ;,表达式:不加分号 ;

Rust 是强类型语言,每个函数参数都需要标注类型,函数的位置可以随便放


  • 垃圾回收机制 (GC),在程序运行时不断寻找不再使用的内存,典型代表:Java、Go
  • 手动管理内存的分配和释放, 在程序中,通过函数调用的方式来申请和释放内存,典型代表:C++
  • 通过所有权来管理内存,编译器在编译时会根据一系列规则进行检查

Rust 中的字符是 Unicode 类型,每个字符占据 4 个字节内存空间;在字符串中不一样,字符串是 UTF-8 编码,字符串中的字符所占的字节数是变化的 (1 - 4),如中文在 UTF-8 中占用三个字节

str 类型是硬编码进可执行文件,也无法被修改,但是 String 则是一个可增长、可改变且具有所有权的 UTF-8 编码字符串。当 Rust 用户提到字符串时,往往指的就是 String 类型和 &str 字符串切片类型,这两个类型都是 UTF-8 编码

元组

1
2
3
fn main() {
    let tup: (i32, f64, u8) = (500, 6.4, 1);
}

. 获取元组中的值


结构体

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
    let user1 = User {
        email: String::from("[email protected]"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };
  // 结构体更新
  let user2 = User {
        email: String::from("[email protected]"),
        ..user1
    };

  • 初始化实例时,每个字段都需要进行初始化
  • 初始化时的字段顺序不需要和结构体定义时的顺序一致

. 访问结构体实例内部的字段值

使用 #[derive(Debug)] 来打印结构体的信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

fn main() {
    let rect1 = Rectangle {
        width: 30,
        height: 50,
    };

    println!("rect1 is {:?}", rect1);
    println!("rect1 is {:#?}", rect1);
}

数组 array

1
2
3
4
5
if condition == true {
    // A...
} else {
    // B...
}

【rust】Option_哔哩哔哩_bilibili

模式匹配: match 和 if let

1
2
3
4
5
6
7
8
9
match target {
    模式1 => 表达式1,
    模式2 => {
        语句1;
        语句2;
        表达式2
    },
    _ => 表达式3
}
1
impl

代码注释

1
2
3
4
5
// 行注释

/* 
    块注释
*/ 

文档注释

1
2
3
4
5
/// 文档行注释

/**
文档块注释
*/

!:宏操作符

Rust 的集合类型不能直接进行循环,需要变成迭代器(可用 .iter() 方法),才能用于迭代循环

随机数:rand


参数解析

clap

1
cargo add clap --features derive
This post is licensed under CC BY 4.0 by the author.