前言
Rust是由Mozilla主导开发的通用、编译型编程语言。设计准则为“安全、并发、实用”,支持函数式、并行式、过程式以及面向对象的程式设计风格。(维基百科)
安装Rust
Linux
1 2
| curl https://sh.rustup.rs -sSf | sh source $HOME/.cargo/env
|
MacOS
直接安装
手动安装
1 2
| brew install rustup-init rustup-init
|
1 2 3 4 5
| 1) Proceed with installation (default) 2) Customize installation 3) Cancel installation
1
|
查看Rust版本
编写Rust代码
- Rust程序会自动导入
prelude
库,无需手动导入即可直接使用
main()
函数为程序的入口
编译单个Rust代码文件
<file>.rs
:Rust源码文件
通过Cargo管理项目
查看Cargo版本
在当前目录初始化项目
- 在当前目录自动创建
Cargo.toml
配置文件,初始化当前目录作为Cargo项目
创建一个新的项目
<project_name>
:项目名称
1
| cargo new <project_name>
|
项目配置文件
package
:当前项目配置
name
:项目名称
version
:项目版本
edition
:使用的Rust版本
dependencies
:第三方依赖crate的配置
Cargo.toml1 2 3 4 5 6 7 8
| [package] name = "demo" version = "0.1.0" edition = "2021"
[dependencies]
|
编译Cargo管理的项目
- 第一次编译时会在项目根目录生成
cargo.lock
文件
- 编译后会在
target
目录下生成可执行文件
编译并运行Cargo管理的项目
为发布而编译
只检查代码不编译
注释
TODO
控制台输出
格式化输出
控制台输入
引入库
1 2 3 4 5 6
| use std::io;
fn main() { let mut str = String::new(); io::stdin().read_line(&mut str).expect("读取输入错误"); }
|
使用全名
1 2 3 4
| fn main() { let mut str = String::new(); std::io::stdin().read_line(&mut str).expect("读取输入错误"); }
|
定义变量
变量的命名规范
- 只能包含小写字母、大写字母、数字、下划线
- 只能以小写字母、大写字母、下划线开头
- 变量名区分大小写
定义不可变的变量(immutable)
定义可变的变量
可变的引用
变量的隐藏
- 定义同名变量,新的变量会将旧的变量隐藏,只保留最后一次定义的结果
1 2
| let 变量名 = 值; let 变量名 = 值;
|
隐藏变量并且改变数据类型
1 2
| let 变量名:数据类型1 = 值; let 变量名:数据类型2 = 值;
|
定义常量
- 常量名称通常是大写字母
- 定义常量时必须指定数据类型
- 常量不能被隐藏,也不能被重复定义
- 常量在编译时就替换为具体的值
运算符
算数运算符
关系运算符
逻辑运算符
位运算
分支语句
if
1 2 3
| if 条件表达式 { 条件表达式为真时执行的语句 }
|
1 2 3 4 5
| if 条件表达式 { 条件表达式为真时执行的语句 } else { 条件表达式不为真时执行的语句 }
|
1 2 3 4 5 6 7
| if 条件表达式1 { 条件表达式1为真时执行的语句 } else if 条件表达式2 { 条件表达式2为真时执行的语句 } else { 条件表达式1和条件表达式2都不为真时执行的语句 }
|
match
- Rust的match语句有返回值,它把匹配值后执行的第一条语句的结果当作返回值
1 2 3 4 5
| let 结果变量名 = match 变量名 { "值1" => 变量结果为值1时返回的值, "值2" => 变量结果为值2时返回的值, _ => 变量结果既不为值1也不为值2时返回的值 }
|
循环语句
while
1 2 3
| while 条件表达式 { 满足条件时反复执行的语句 }
|
for
遍历有序的整数
遍历可迭代对象
迭代后元素保持不变
1 2 3 4
| let list = vec!["", ""]; for item in list.iter() { ... }
|
迭代后会将元素移除
1 2 3 4
| let list = vec!["", ""]; for item in list.into_iter() { ... }
|
迭代时可以修改元素值
1 2 3 4
| let mut list = vec!["", ""]; for item in list.iter_mut() { ... }
|
loop
1 2 3 4 5 6 7
| let mut flag = true loop { if flag == false { break; } flag = false; }
|
所有权
- Rust中在栈中存储的数据(基本类型数据)不会涉及到所有权的迁移
- Rust中在堆中存储的数据(引用类型数据)有所有权,每个数据只能由一个变量所有,当发生转移的时候新的变量获得所有权,旧的变量失去所有权,失去所有权的变量将不能再使用这个变量
转移所有权
通过赋值转移所有权
1 2
| let 变量名1:引用类型 = 值; let 变量名2 = 变量名1;
|
通过函数参数的传递转移所有权
1 2
| let 变量名1:引用类型 = 值; 函数名(变量名1);
|
借用
- 通过使用
&
修饰的变量实现对所有权的借用
- 在函数执行结束会自动归还所有权
1 2
| let mut 变量名1:引用类型 = 值; 函数名(&mut 变量名1);
|
解构结构体
1 2 3 4 5 6 7
| let 结构体变量名 = 结构体名{ 属性名: 属性值 };
let 结构体名 { 属性名: 属性名 } = 结构体变量名;
|
只解构部分属性
..
:忽略其他属性
1 2 3 4 5 6 7 8 9
| let 结构体变量名 = 结构体名{ 属性名1: 属性值, 属性名2: 属性值 };
let 结构体名 { 属性名1: 属性名1, .. } = 结构体变量名;
|
判断是否能正常解构
1 2 3 4 5 6 7 8 9 10
| let 结构体变量名 = 结构体名{ 属性名1: 属性值, 属性名2: 属性值 };
if let 结构体名 {属性名: 属性名} = 结构体变量名 { 解构成功时执行的语句 } else { 解构失败时执行的语句 }
|
1 2 3 4 5 6 7 8
| let 结构体变量名 = 结构体名{ 属性名1: 属性值, 属性名2: 属性值 };
while let 结构体名 {属性名: 属性名} = 结构体变量名 { 解构成功时反复执行的语句 }
|
完成
参考文献
哔哩哔哩——软件工艺师
哔哩哔哩——面向加薪学习
知乎——赵东颖