目录

第一章 Rust基础

1.1 Rust简介与安装

什么是Rust

Rust是一门专注于安全、速度和并发性的系统编程语言。它由Graydon Hoare在2006年开始设计,2010年由Mozilla正式发布。Rust的设计目标是提供C++级别的性能和控制,同时保证内存安全和线程安全。

Rust的主要优势:

  1. 内存安全:通过所有权系统消除空指针、悬垂指针、数据竞争等问题
  2. 零成本抽象:高级特性不带来运行时开销
  3. 现代化工具链:Cargo包管理器、内置测试、文档生成
  4. 跨平台:支持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的构建系统、包管理器和通用工具。它能够:

创建新项目

使用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 <email@example.com>"]
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

代码解析

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的区别:

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最核心的特性——所有权系统,这是理解Rust内存管理的关键。