====== 第一章 Rust基础 ======
===== 1.1 Rust简介与安装 =====
==== 什么是Rust ====
Rust是一门专注于安全、速度和并发性的系统编程语言。它由Graydon Hoare在2006年开始设计,2010年由Mozilla正式发布。Rust的设计目标是提供C++级别的性能和控制,同时保证内存安全和线程安全。
**Rust的主要优势:**
- **内存安全**:通过所有权系统消除空指针、悬垂指针、数据竞争等问题
- **零成本抽象**:高级特性不带来运行时开销
- **现代化工具链**:Cargo包管理器、内置测试、文档生成
- **跨平台**:支持Windows、macOS、Linux及嵌入式平台
==== 安装Rust ====
Rust通过**rustup**工具链安装管理器进行安装,这是官方推荐的安装方式。
**Linux/macOS安装:**
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
**Windows安装:**
访问 https://rustup.rs/ 下载并运行 rustup-init.exe
安装完成后,需要重新加载环境变量或重启终端:
source $HOME/.cargo/env # Linux/macOS
==== 验证安装 ====
安装完成后,验证Rust是否正确安装:
# 查看Rust编译器版本
rustc --version
# 输出示例:rustc 1.75.0 (82e1608df 2023-12-21)
# 查看Cargo版本
cargo --version
# 输出示例:cargo 1.75.0
===== 1.2 Cargo:Rust的构建工具和包管理器 =====
==== Cargo是什么 ====
Cargo是Rust的构建系统、包管理器和通用工具。它能够:
* 构建代码(编译项目)
* 下载并管理依赖库
* 运行测试
* 生成文档
* 发布到 crates.io
==== 创建新项目 ====
使用cargo new创建新项目:
# 创建可执行程序项目
cargo new hello_cargo
cd hello_cargo
# 创建库项目
cargo new my_library --lib
项目结构:
hello_cargo/
├── Cargo.toml # 项目配置和依赖
├── .gitignore # Git忽略文件
└── src/
└── main.rs # 程序入口
==== Cargo.toml详解 ====
Cargo.toml是项目的配置文件,使用TOML格式:
[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"
authors = ["Your Name "]
description = "A sample project"
license = "MIT OR Apache-2.0"
repository = "https://github.com/username/hello_cargo"
[dependencies]
# 依赖库
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
[dev-dependencies]
# 开发依赖
[[bin]]
# 可执行文件配置
name = "hello_cargo"
path = "src/main.rs"
==== Cargo常用命令 ====
cargo new project_name # 创建新项目
cargo build # 编译项目(debug模式)
cargo build --release # 编译优化版本
cargo run # 编译并运行
cargo check # 快速检查代码(不生成可执行文件)
cargo test # 运行测试
cargo doc # 生成文档
cargo doc --open # 生成并打开文档
cargo publish # 发布到crates.io
cargo update # 更新依赖
cargo clean # 清理构建产物
===== 1.3 编写第一个Rust程序 =====
==== Hello, World! ====
编辑 src/main.rs:
fn main() {
println!("Hello, World!");
}
运行程序:
cargo run
==== 代码解析 ====
* **fn main()**:程序的入口函数,每个可执行程序必须有一个
* **println!**:宏(macro),用于打印到控制台并换行
* **分号**:Rust语句以分号结尾
===== 1.4 基本语法 =====
==== 变量与可变性 ====
Rust默认变量是不可变的(immutable):
fn main() {
let x = 5;
println!("x的值为:{}", x);
// x = 6; // 错误!不能修改不可变变量
let mut y = 5; // mut表示可变
println!("y的值为:{}", y);
y = 6; // 正确
println!("y的新值为:{}", y);
}
==== 常量 ====
常量在编译期确定,且总是不可变的:
const MAX_POINTS: u32 = 100_000;
const PI: f64 = 3.14159;
常量的命名规范:全大写,单词间用下划线分隔。
==== 变量遮蔽(Shadowing) ====
可以声明同名新变量来遮蔽旧变量:
fn main() {
let x = 5;
let x = x + 1; // 新x遮蔽旧x
let x = x * 2; // 再次遮蔽
println!("x的值为:{}", x); // 输出:12
// 可以改变类型
let spaces = " ";
let spaces = spaces.len(); // 从&str变成usize
}
遮蔽与mut的区别:
* 遮蔽创建新变量,可以改类型
* mut修改同一变量,不能改类型
===== 1.5 数据类型 =====
Rust是静态类型语言,编译时必须知道所有变量的类型。
==== 标量类型 ====
**整数类型:**
| 长度 | 有符号 | 无符号 |
|------|--------|--------|
| 8-bit | i8 | u8 |
| 16-bit | i16 | u16 |
| 32-bit | i32 | u32 |
| 64-bit | i64 | u64 |
| 128-bit | i128 | u128 |
| arch | isize | usize |
let a: i32 = 98_222; // 十进制
let b: i32 = 0xff; // 十六进制
let c: i32 = 0o77; // 八进制
let d: i32 = 0b1111_0000; // 二进制
let e: u8 = b'A'; // 字节(仅限于u8)
**浮点类型:**
let x = 2.0; // f64(默认)
let y: f32 = 3.0; // f32
**布尔类型:**
let t = true;
let f: bool = false;
**字符类型:**
let c = 'z';
let z: char = 'ℤ';
let heart_eyed_cat = '😻'; // Unicode标量值
==== 复合类型 ====
**元组(Tuple):**
固定长度,可以包含不同类型:
let tup: (i32, f64, u8) = (500, 6.4, 1);
// 解构
let (x, y, z) = tup;
// 通过索引访问
let five_hundred = tup.0;
let six_point_four = tup.1;
**数组(Array):**
固定长度,元素类型相同:
let a = [1, 2, 3, 4, 5];
let months = ["January", "February", "March"];
// 指定类型和长度
let a: [i32; 5] = [1, 2, 3, 4, 5];
// 初始化5个3
let a = [3; 5]; // [3, 3, 3, 3, 3]
// 访问元素
let first = a[0];
let second = a[1];
===== 1.6 函数 =====
==== 定义函数 ====
fn main() {
println!("Hello, world!");
another_function();
}
fn another_function() {
println!("另一个函数!");
}
==== 函数参数 ====
fn main() {
print_labeled_measurement(5, 'h');
}
fn print_labeled_measurement(value: i32, unit_label: char) {
println!("测量值:{}{}", value, unit_label);
}
==== 语句与表达式 ====
* **语句**:执行操作但不返回值
* **表达式**:计算并返回值
fn main() {
let y = {
let x = 3;
x + 1 // 表达式(没有分号)
};
println!("y的值为:{}", y); // 4
}
==== 返回值 ====
fn five() -> i32 {
5 // 隐式返回(无分号)
}
fn plus_one(x: i32) -> i32 {
x + 1 // 也可以写 return x + 1;
}
fn main() {
let x = five();
println!("five()返回:{}", x);
let y = plus_one(5);
println!("plus_one(5)返回:{}", y);
}
===== 1.7 注释 =====
// 单行注释
/*
* 块注释
* 可以跨多行
*/
/// 文档注释(用于函数、结构体等)
fn documented_function() {}
/*!
* 模块级文档注释
*/
===== 1.8 控制流 =====
==== if表达式 ====
let number = 6;
if number % 4 == 0 {
println!("能被4整除");
} else if number % 3 == 0 {
println!("能被3整除");
} else if number % 2 == 0 {
println!("能被2整除");
} else {
println!("不能被4、3或2整除");
}
if是表达式,可以用于赋值:
let condition = true;
let number = if condition { 5 } else { 6 };
==== 循环 ====
**loop:无限循环**
let mut counter = 0;
let result = loop {
counter += 1;
if counter == 10 {
break counter * 2; // 返回值
}
};
println!("结果:{}", result); // 20
**while条件循环:**
let mut number = 3;
while number != 0 {
println!("{}!", number);
number -= 1;
}
println!("发射!");
**for遍历:**
let a = [10, 20, 30, 40, 50];
for element in a.iter() {
println!("值为:{}", element);
}
// 范围遍历
for number in 1..4 { // 1, 2, 3
println!("{}!", number);
}
// 包含4
for number in 1..=4 { // 1, 2, 3, 4
println!("{}!", number);
}
// 反向
for number in (1..4).rev() {
println!("{}!", number);
}
===== 练习题 =====
==== 练习题1.1:温度转换 ====
编写程序将华氏度转换为摄氏度,或反之。公式:C = (F - 32) × 5/9
fn fahrenheit_to_celsius(f: f64) -> f64 {
(f - 32.0) * 5.0 / 9.0
}
fn celsius_to_fahrenheit(c: f64) -> f64 {
c * 9.0 / 5.0 + 32.0
}
fn main() {
let f = 68.0;
let c = fahrenheit_to_celsius(f);
println!("{}°F = {:.2}°C", f, c);
}
==== 练习题1.2:斐波那契数列 ====
生成第n个斐波那契数。
fn fibonacci(n: u32) -> u32 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
fn main() {
for i in 0..10 {
println!("fib({}) = {}", i, fibonacci(i));
}
}
==== 练习题1.3:圣诞颂歌 ====
使用循环打印"The Twelve Days of Christmas"的歌词。
fn main() {
let days = ["first", "second", "third", "fourth", "fifth", "sixth",
"seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth"];
let gifts = [
"a partridge in a pear tree",
"two turtle doves",
"three French hens",
"four calling birds",
"five golden rings",
"six geese a-laying",
"seven swans a-swimming",
"eight maids a-milking",
"nine ladies dancing",
"ten lords a-leaping",
"eleven pipers piping",
"twelve drummers drumming"
];
for day in 0..12 {
println!("On the {} day of Christmas, my true love gave to me:", days[day]);
for gift in (0..=day).rev() {
if gift == 0 && day != 0 {
print!("And ");
}
println!("{}", gifts[gift]);
}
println!();
}
}
===== 本章小结 =====
本章介绍了Rust的基础知识:
* Rust通过rustup安装,Cargo是构建工具和包管理器
* 变量默认不可变,使用mut关键字使其可变
* Rust有四种标量类型:整数、浮点、布尔、字符
* 两种复合类型:元组(固定长度、不同类型)和数组(固定长度、相同类型)
* 函数参数必须声明类型,语句无返回值,表达式有返回值
* 控制流包括if表达式、loop、while和for循环
在下一章中,我们将深入探讨Rust最核心的特性——**所有权系统**,这是理解Rust内存管理的关键。