Rust学习笔记(一)
Rust 笔记
一、Cargo 项目管理
Rust 推荐使用 Cargo 管理项目。
常用命令
# 编译文件
rustc 文件名
# 运行文件
rust 编译后的文件
Cargo 命令
# 检查版本
cargo --version
# 创建项目
cargo new 项目名
# 构建项目
cargo build
# 构建并运行
cargo run
# 检查项目,不生成二进制文件
cargo check
# 发布构建(优化编译,在 target/release 下生成可执行文件)
cargo build --release
# 将文件转化为 cargo 项目
cargo init
文件结构
Cargo.toml是项目的配置文件[package]是一个 section 标题,表明是在配置一个 packagename项目名称,version项目版本,edition项目使用的 Rust edition[dependencies]是项目依赖列表,Rust 中代码包被称为 crates
二、变量与常量
变量定义
let 变量 = 值;
Rust 默认变量不可变,即 let 之后不可再次赋值。
若需要修改,需要使用 mut 关键字:
let mut 变量 = 值;
常量
const 常量: 类型 = 值;
Rust 变量默认为不可变变量,但与常量有很大区别:
| 特性 | 常量 | 变量 |
|---|---|---|
| 值确定时机 | 编译期,运行时不变化 | 运行时创建 |
| 生命周期 | 全局有效,无生命周期 | 有作用域和生命周期 |
| 遮蔽 | 不可被遮蔽 | 可以被遮蔽 |
| 类型标注 | 需要写明类型 | 可推导类型 |
| 初始化值 | 只能是常量表达式 | 可以是表达式、函数结果等 |
变量遮蔽
Rust 允许重复定义变量,旧值不会被销毁,而是被"遮蔽":
fn main() {
let x = 5; // x 值为 5
let x = x + 1; // 原 x (值为5) 被 x+1 (值为6) 遮蔽
{
let x = x * 2; // 外层 x (值为6) 被 x*2 (值为12) 遮蔽
println!("The value of x in the inner scope is: {x}");
}
// 内层遮蔽结束,恢复为外层 x (值为6)
println!("The value of x is: {x}");
}
输出:
The value of x in the inner scope is: 12
The value of x is: 6
三、数据类型
标量类型
Rust 有四种基本的标量类型:整型、浮点型、布尔类型和字符类型。
整型
| 长度 | 有符号 | 无符号 |
|---|---|---|
| 8-bit | i8 | u8 |
| 16-bit | i16 | u16 |
| 32-bit | i32 | u32 |
| 64-bit | i64 | u64 |
| 128-bit | i128 | u128 |
| 架构相关 | isize | usize |
i是有符号整数(包含负数、0 和正数)u是无符号整数(只包含 0 和正数)isize/usize由设备位数决定,64 位架构上等同 i64/u64,32 位架构上等同 i32/u32
浮点型
| 类型 | 说明 |
|---|---|
| f32 | 32 位浮点数 |
| f64 | 64 位浮点数(默认) |
布尔型
true
false
字符型
char
复合类型
复合类型可以把多个值组合成一个类型。Rust 有两种原生的复合类型:元组(tuple) 和 数组(array)。
元组
将多个不同类型的值组成一个复合类型,声明后长度和大小不可变。
// 定义
let 元组 = (值, 值);
let 元组: (类型, 类型, 类型) = (值, 值, 值);
// 解构
let (变量, 变量, 变量) = 元组;
// 索引访问
元组.索引
数组
数组声明后不可改变长度和类型。
let 数组: [类型] = [元素];
let a: [i32; 5] = [1, 2, 3, 4, 5];
let a = [3; 5]; // 等同于 [3, 3, 3, 3, 3]
// 访问
数组[索引]
四、函数
函数定义
fn 函数名() {
// ...
}
fn 函数名(形参: 类型) -> 返回类型 {
// ...
}
语句与表达式
- 语句(Statements):执行操作但不返回值
- 表达式(Expressions):计算并产生一个值
let y = 6; // 语句(带分号)
let y = 6 // 表达式(无分号)
函数本身是一个语句,但调用函数是一个表达式,因为它有返回值。
五、控制流
if 表达式
if 条件 {
// ...
} else if 条件 {
// ...
} else {
// ...
}
if 本身是一个表达式,可以用在 let 赋值中:
let 变量 = if 条件 { 值 } else { 值 };
注意:if 返回的值的类型必须一致。
loop 循环
loop {
// ...
}
break 跳出循环。loop 本身也是表达式,可用 break 带返回值:
fn main() {
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2;
}
};
println!("The result is {result}");
}
循环标签
'标签: loop {
// ...
loop {
// ...
break '标签;
}
}
break '标签 跳出被标签标记的 loop 循环。
while 和 for 循环
for 循环可以遍历 (1..4) 这样的范围集合:
fn main() {
for number in (1..4).rev() {
println!("{number}!");
}
println!("LIFTOFF!!!");
}