Rust由Mozila开发,是一款免费开源的高级编程语言。

以高性能、高可靠性和高生产力著称。
可以用于系统编程、web编程、服务器开发和嵌入式等开发。

统一问题

  1. 系统和内存安全
  2. 性能优化和提升

Why Rust?

  • 高性能web services
  • WebAssembly
  • 网络编程
  • 嵌入式
  • 系统编程
  • 引擎开发

参考材料

安装

windows+MinGW+Rust 安装

  1. Windows安装MinGW
  2. 下载rustup-init.exe
  3. 设置CARGO_HOME=D:\program_lang\rust64\cargo; RUSTUP_HOME=D:\program_lang\rust64\rustup;D:\program_lang\rust64\cargo\bin加入到path
  4. 双击rustup-init.exe
 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
urrent installation options:

   default host triple: x86_64-pc-windows-msvc
     default toolchain: stable (default)
               profile: default
  modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>2

I'm going to ask you the value of each of these installation options.
You may simply press the Enter key to leave unchanged.

Default host triple? [x86_64-pc-windows-msvc]
x86_64-pc-windows-gnu

Default toolchain? (stable/beta/nightly/none) [stable]
stable

Profile (which tools and data to install)? (minimal/default/complete) [default]
complete

Modify PATH variable? (Y/n)
Y

Current installation options:

   default host triple: x86_64-pc-windows-gnu
     default toolchain: stable
               profile: complete
  modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
>
  1. rust版本查看;cargo版本查看
1
2
3
4
5
6
7
8
9
# 查看版本
rustc --version
cargo --version
# 更新rust的版本
rustup update
# 卸载rust
rustup self uninstall
# 查看rust的本地的document
rustup doc

cargo包管理

  • rust的构建系统和包管理工具

    构建代码、 下载依赖库等

  • 创建Cargo项目

 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
54
55
56
57
58
59
60
61
62
63
# 查看cargo【安装rust时就已经安装好cargo】
cargo --version

# 创建cargo项目
cargo new hello_rust

# 形成一个文件目录
.
+--- .git
+--- .gitignore
+--- Cargo.toml
+--- src
|   +--- main.rs

# Cargo.toml 【Tom's Obvious,MInimal Language】
# cargo 的配置格式
[package]
name = "hello_rust"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rand = "0.3" # 基于Rust官方仓库crates.io,通过版本说明来描述
hammer = { version = "0.5.0"}
color = { git = "https://github.com/bjz/color-rs" } #基于项目源代码的git仓库地址,通过 URL 来描述
geometry = { path = "crates/geometry" } #基于本地项目的绝对路径或者相对路径,通过类Unix模式的路径来描述

# src 源代码目录

# cargo buid 
1. 会生成cargo.lock 精确记录项目的依赖
2. 自动维护,不需要

# cargo run
1. 先编译,后执行
2. 执行前会比较最近一次的编译,没变将会直接执行

# cargo check 检查代码,确保能通过编译,不会产生任何执行文件
1. 比cargo build快的多
2. 只是检查编译是否能通过,在反复检验时,效率会很高

# cargo build --release 发布使用
1. target/release # 发布版本会在此形成,编译会很慢
2. target/debug

# crates.io的换成国内镜像源
cd $HOME
mkdir .cargo & cd .cargo
vim config.toml
# 写入一些内容
[source.crates-io]
replace-with = 'rsproxy'

[source.rsproxy]
registry = "https://rsproxy.cn/crates.io-index"

[registries.rsproxy]
index = "https://rsproxy.cn/crates.io-index"

[net]
git-fetch-with-cli = true

cargo主要命令:cargo -h查看cargo命令

命令 功能
cargo new 新建项目
cargo build 编译项目
cargo check 检查项目是否存在错误,不进行编译
cargo run 编译运行项目
cargo test 测试项目
cargo doc 构建项目文档
cargo publish 将库发布到crates.io
cargo clean 移除项目张target文件夹及其所有子文件夹和文件
cargo update 更新项目的所有依赖

计算机基础

不管上层有多绚烂, 只要现有计算架构不变, 底层永远还是那些

内存

问题: 数据什么时候放在栈上, 什么时候需要放在堆上?

编译器编译和优化的单元是:函数. 编译器需要完成:

  1. 需要使用那些寄存器, 如何分配和使用
  2. 那些数据需要分配到栈上, 或者分配到堆上
  3. 明确数据的大小以及如何预留足够运行存储空间

回答: 编译时, 一切无法确定大小或大小可改变的数据, 都无法安全存于栈上, 最好存于堆上.

总结:

  1. 栈上内存数据是静态的, 静态大小, 静态生命周期
  2. 堆上存放数据是动态的, 动态大小, 动态生命周期

理解: 清晰知道,哪些东西在编译期间可以确定他们之间的关系或者因果, 哪些只能在运行期间确定.

程序操作对象: 数据 [值/类型/指针/引用]

数值就是数值, 类型赋予数值"形态": 长度, 对齐以及值的运算.

指针和引用是原生类型, 可以分配在栈上.

程序运行主体: 代码 [函数/方法/闭包/接口/虚表]

程序执行效率: 运行方式 [并发/并行/同步/异步]

程序结构质量: 编程范式 [泛型编程]

语法基础

变量

  • 变量声明–let var: type = valuse;
  • 变量绑定–所有权的接触和获得
  • 变量可变–默认不可变,即变量一旦被绑定就不会再被绑定->平衡更新和复制
  • 变量遮蔽–变量名称相同但是不同的内存空间 let x=3; let x="rust";
1
2
3
4
5
6
7
fn main() {
    // let x = 5;  x只读不能在赋值 如x=3; 
    let mut x: i32 = 5;  // 通过mut关键字使得编译该变量为可读写
    println!("The value is: {}", x);  // {} 格式化占位输出
    x = 6;
    println!("The value is: {}", x);
}
  • 析构
1
let (a, mut b): (bool, bool) = (false, false);
  • 常量–编译完成后就确定值,且全程不可修改
  • 常量可以在任意作用域使用,需要显式声明
1
2
const MAX_POINTS: u32 = 10_000;
static LANGUAGE: &'static str = "Rust";
  • 重复声明变量–shadowing–>内存再分配

结构体

 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
// 结构体类型
struct Person {
    name: String,
    age: u8
}

// 空结构体 
struct Unit;

// 元组结构体
struct Pair(i32, f32);

struct Point {
    x: f32,
    y: f32,
}

// 结构体混合
#[allow(dead_code)]
struct Rectangle {
    top_left: Point,
    bottom_right: Point,
}

fn main() {
    let name = String::from("CodeDucker");
    let age = 27;
    let ducker = Person{name, age};
    println!("name: {} age: {}", ducker.name, ducker.age);

    let point = Point{x: 10.3, y: 0.4};
    println!("point {} {}", point.x, point.y);
    // 结构体复用结构体内容
    let bottom_right = Point{x: 5.2, ..point};
    println!("bottom point: {} {}", bottom_right.x, bottom_right.y);

    // 结构体解构 bootom_right 拆分赋值
    let Point{x: left_edge, y: right_edge} = point;

    let _rectangle = Rectangle {
        top_left: Point { x: left_edge, y: right_edge },
        bottom_right: bottom_right,
    };

    let _unit = Unit;

    let pair = Pair(1, 0.1);
    let Pair(integer, decimal) = pair;
    println!("pair {} {}", integer, decimal);
}

eunm 枚举类型

 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
// 枚举类型
// 关键字 enum
// 枚举名::枚举值
// 枚举更像是一定范围内确定性的匹配限制
enum WebEvent {
    // 单元结构体
    PageLoad,
    PageUnload,
    // 元组结构体
    Keypress(char),
    Paste(String, i64),
    // 一般结构体
    Click{x: i64, y: i64},
}

fn inspect(event: WebEvent) {
    match event {
        WebEvent::PageLoad => println!("Page Load"),
        WebEvent::PageUnload => println!("Page Unload"),
        WebEvent::Keypress(c) => println!("pressed '{}.'", c),
        WebEvent::Paste(s, age) => println!("pasted \"{} {}.\"", s, age),
        WebEvent::Click { x, y } => {
            println!("clicked at x={} y={}", x, y);
        },
    }
}

fn main() {
    let pressed = WebEvent::Keypress('x');
    let pasted = WebEvent::Paste("my age is".to_owned(), 30);
    let click = WebEvent::Click { x: 20, y: 80 };
    let load = WebEvent::PageLoad;
    let unload = WebEvent::PageUnload;

    inspect(pressed);
    inspect(pasted);
    inspect(click);
    inspect(load);
    inspect(unload);
}