Lazy loaded image
语言与算法
Rust 基础语法学习笔记
字数 17221阅读时长 44 分钟
2025-12-5
2026-9-15

1. Rust与C/C++的区别

Rust可以替换C/C++,和他们有同样的性能,但是很多bug在编译时就被消灭了。
它更善于以下场景
  • 需要运行速度
  • 需要内存安全
  • 需要更好的利用多处理器

1. 内存管理:手动 vs 所有权系统

Rust是一个用栈内存管理堆内存的设计,所以作用域(函数)结束,运行栈的数据会被全部释放,如果后面还有要用的数据,要么返回(移交所有权),要么提前说明是借用(可变引用或不可变引用)(借别人的就得还);这就是内存管理的精髓
notion image

C/C++ 怎么做

  • C:malloc/free,很容易:
    • 忘记 free → 内存泄漏
    • 重复 free → 野指针、崩溃
  • C++:new/delete + RAII/智能指针(std::unique_ptr 等)
    • 写得好很安全,但要自觉、要有规范

Rust 怎么做

Rust 禁止手动 free,通过「所有权」和「作用域」在编译期自动管理:
关键规则只有三条:
  1. 每个值有且只有一个所有者(owner)
  1. 所有者离开作用域时,值会被自动释放
  1. 同一时刻(只能有一个主人):
      • 要么有任意多个不可变引用 &T(也就是读随便你读)
      • 要么有一个可变引用 &mut T,不能混用 (写时同一时刻只能有一个写)
感受差异:
  • C/C++:内存安全靠程序员经验和自觉
  • Rust:编译器强制你写出「不会有悬垂指针、UAF(use-after-free)」的代码,否则不让编译过,这点非常关键:设备跑久了不崩,不泄漏。

2. 空指针 & 错误处理:裸指针 vs Option / Result

C/C++:NULL / nullptr + 错误码或异常

很多 BUG 都是「忘了判空」,或者「return -1 表示错误,但上层没处理」。

Rust:没有「空指针」这个类型,用枚举强制你处理

  • 没有「默认可以是空」的指针
  • 用:
    示例:
    差异点:
    • C:NULL + 注释告诉你「可能为空」
    • Rust:类型系统直接告诉你「这个函数可能没有值/会失败」,不处理就过不了编译,Rust 会强迫你都考虑到。

    3. 并发与多线程:野蛮 vs 编译期保护

    C/C++:线程安全全靠规范

    • 多线程时:
      • 不加锁 → 数据竞争
      • 加锁忘了释放 → 死锁
      • 用错锁 → 逻辑乱

    Rust:设计目标就是「无数据竞争的并发」

    核心思想:
    • 只要有数据竞争风险的代码,一律编译不过
    • Send / Sync 这两个 trait,控制「什么类型能在线程间移动 / 共享」
    示例:
    要在多线程之间共享数据,你必须显式使用:
    • Arc<T>:原子引用计数,线程安全的共享指针
    • Mutex<T>:互斥锁
    • 或者 channel:消息传递
    差异:
    • C/C++:你想干啥都行,但错了就 UB(未定义行为)
    • Rust:你只有「安全地干」这一条路(当然也可以 unsafe 强行绕过,但需要你非常清楚自己在干啥)

    4. 语言特性:更现代、约束更多

    4.1 所有权 + 借用 vs 借引用自己约束

    在 C++ 里你经常会写:
    Rust 里借用概念被提升到核心语言层级
    区别在于:
    • Rust 有 borrow checker(借用检查器),在编译时验证:
      • 不会有悬垂引用
      • 同一时间只有一个 &mut 或多个 &
    • C++ 靠你自觉,语法本身不会帮你做严格检查

    4.2 泛型 & trait vs 模板 & 继承

    • C++:模板(template)+ 虚函数 / 继承
    • Rust:泛型 + trait(更偏向接口 + 约束)
    对这种以后会有「LED、继电器、传感器」等不同设备类型的场景,trait 非常适合抽象接口,比 C++ 继承+虚函数更「松耦合」。

    1.5 工具链与生态:cargo 一站式 vs 各种 build 系统

    C/C++ 常见情况

    • 构建系统:Makefile / CMake / qmake / autotools 等
    • 依赖管理:
      • 自己下载源码,放到项目里
      • 或者系统包管理器(apt, yum 等)
    不同项目结构都不一样,需要你自己整。

    Rust:全都交给 cargo

    一个命令初始化项目:
    依赖管理、构建、测试、格式化,一条龙:
    依赖写在 Cargo.toml 里:
    你在 Linux 上写 Matter Controller / 服务端逻辑时:
    • 想用 HTTP 客户端、MQTT、数据库,只要在 Cargo.toml 添一行,然后 cargo build 就能自动拉下来
    • 不用自己折腾库路径、版本冲突(一部分工作交给了 Cargo)

    1.6 运行时 & 性能:接近 C,但更可控

    共同点

    • 都是编译型语言,生成机器码
    • 性能上基本同级(Rust 通常和 C++ 打个平手,甚至有场景更快)

    不同点

    • Rust 没有 GC(垃圾回收),性能可预测,适合嵌入式
    • Rust 引用在语义上更接近「受约束的指针」
    • panic(类似断言失败)默认不会像 C++ 异常那样无处不在,它是显式的,且可以在嵌入式环境下关闭 unwind 改为 abort
    对于 ESP32 / Linux 这种场景:
    • ESP32:可以用 no_std + 特定运行时,控制栈、堆的使用,甚至替换分配器
    • Linux:可以直接用完整标准库,配合 tokio 之类的异步运行时写高并发服务

    1.7 unsafe:可以接近 C,但要「圈起来」

    Rust 有 unsafe不安全的)关键字,允许你:
    • 直接操作裸指针
    • 调用 C 函数(FFI)
    • 读写某些特殊内存(寄存器、MMIO 等)
    关键区别:
    • C:所有地方都「默认 unsafe」
    • Rust:默认安全,只有 unsafe 块里你要自己保证安全性,而且很醒目
    在嵌入式(ESP32)开发里,这就很有用:
    • 大部分逻辑用安全 Rust 写
    • 必须直接操作寄存器或调用 ESP-IDF C API 的地方,用 unsafe 包一小块
    • 将风险范围缩到最小

    8. 学 Rust 主要要「转的几个弯」

    1. 忘掉手动 free:
        • 不要想着「我什么时候 free」
        • 要想着「这个值应该归谁管?它的生命周期到哪?」
        • 尤其是函数参数/返回值,先大胆用「按值传递」,编译器会帮你优化。
    1. 习惯 Option / Result
        • 思维从「这个函数返回 NULL / -1」
        • 转成「这个函数可能返回 None / Err,要么我处理,要么向上抛」。
    1. 接受借用检查器的“刁难”:
        • 一开始会觉得编译器很烦,但每一个错误都是在防止潜在 bug
        • 常见模式:先写成「克隆一份」(clone()),跑通功能,再优化所有权设计。
    1. 习惯用 cargo 管理项目:
        • 不再手写 Makefile / CMake
        • cargo new / cargo build / cargo run 就够你 90% 的需求。
    1. 并发用通道/锁,不直接共享裸指针:
        • 多线程优先考虑「消息传递」而不是「共享内存」
        • 共享必须用 Arc<Mutex<T>> 之类的包装。

    2. Cargo

    • 可以使用 cargo new 创建项目。
    • 可以使用 cargo init 来初始化当前文件夹为项目文件夹
    • 可以使用 cargo build 构建项目。
    • 可以使用 cargo build --release优化编译最终发布的版本
    • 可以使用 cargo run 一步构建并运行项目。
    • 可以使用 cargo check 在不生成二进制文件的情况下构建项目来检查错误。
    • 可以使用 cargo add 添加外部的依赖
    • 可以使用 cargo update更新外部的依赖1
    • 可以在 Crates.io 搜索依赖包,也可以直接cargo search
    你不可能凭空就知道应该 use 哪个 trait 以及该从 crate 中调用哪个方法,因此每个 crate 有使用说明文档。Cargo 的另一个很棒的功能是运行 cargo doc --open 命令来构建所有本地依赖提供的文档并在浏览器中打开。例如,假设你对 rand crate 中的其他功能感兴趣,你可以运行 cargo doc --open 并点击左侧导航栏中的 rand

    3. 初识(找数字游戏)

    一个简单的模块, 介绍:

    4. 基础语法

    4.1 Rust 变量和常量详解

    • 变量绑定:Rust 的变量默认为不可变(immutable),使用 let 关键字绑定值。如果想要使变量可变,需要添加 mut 关键字。
    • 可变性(mutability):通过在变量声明前添加 mut 关键字,使变量可变,这样你可以在后续的代码中改变它的值。
    • 常量:类似于不可变变量,常量 (constants) 是绑定到一个名称的不允许改变的值,常量在整个程序生命周期中都有效
    • 变量和常量的区别:
          1. 常量使用const关键字,变量使用let关键字
          1. 常量必须标注类型,变量可以自动推断类型
          1. 常量的值必须是编译时已知的
          1. 常量可以在任何作用域中声明,包括全局作用域
          1. 常量只能被设置为常量表达式,无法绑定到函数的调用结果或只能在运行时才能计算出的值。
    命名规范:Rust里,常量使用全大写字母,单词中间使用下划线分开例如:const MAX_NUM:u32 = 100_000; 数字之间可以使用_ 来增强可读性

    4.2 Rust 数据类型详解

    let tuple_1 = (10, "hello", 3.14); // 类型自动推断为(i32, &str, f64)
    let tuple_2: (i32, &str, f64) = (20, "world", 2.71); // 显式指定类型
    println!("n元组类型示例:");
    println!("tuple_1: {:?}", tuple_1);
    println!("tuple_2: {:?}", tuple_2);
    // 解构元组
    // 可以使用模式匹配来解构元组的值
    let (x, y, z) = tuple_1;
    println!("解构元组: x={}, y={}, z={}", x, y, z);
    // 数组类型
    // 数组是将多个相同类型的值组合在一起的方式
    // 数组的长度是固定的,一旦声明就不能改变大小
    let array_1 = [1, 2, 3, 4, 5]; // 类型自动推断为[i32; 5]
    let array_2: [i32; 5] = [10, 20, 30, 40, 50]; // 显式指定类型和长度
    let array_3 = [3; 5]; // 重复初始化:创建包含5个3的数组
    println!("n数组类型示例:");
    println!("array_1: {:?}", array_1);
    println!("array_2: {:?}", array_2);
    println!("array_3: {:?}", array_3);
    // 访问数组元素
    // 可以使用索引来访问数组中的元素,索引从0开始
    println!("array_1[0]: {}, array_2[2]: {}", array_1[0], array_2[2]);
    // 切片类型
    // 切片允许我们引用集合中一段连续的元素序列,而不是整个集合
    // 切片是引用,所以没有所有权
    let slice_1 = &array_1[1..4]; // 引用array_1中从索引1到3的元素(不包含4)
    let slice_2 = &array_2[..3]; // 引用array_2中从开始到索引2的元素
    println!("n切片类型示例:");
    println!("slice_1: {:?}", slice_1);
    println!("slice_2: {:?}", slice_2);
    }
    // 函数定义
    fn add(a: i32, b: i32) -> i32 {
    a + b // 表达式作为返回值,不需要分号
    }
    // 带多个参数的函数
    fn multiply(a: i32, b: i32, c: i32) -> i32 {
    a b c
    }
    // 无返回值的函数
    fn print_greeting(name: &str) {
    println!("Hello, {}!", name);
    }
    // 带返回值的函数,使用return关键字
    fn divide(a: i32, b: i32) -> i32 {
    if b == 0 {
    return 0; // 提前返回
    }
    a / b
    }
    // 函数参数可以有默认值
    fn greet(name: &str, greeting: &str) {
    println!("{} {}", greeting, name);
    }
    // 可变参数函数
    fn sum(numbers: &[i32]) -> i32 {
    let mut total = 0;
    for &num in numbers {
    total += num;
    }
    total
    }
    // 嵌套函数
    fn outer_function() {
    println!("This is the outer function");
    fn inner_function() {
    println!("This is the inner function");
    }
    inner_function();
    }
    // 函数作为参数
    fn apply_function<F>(f: F, x: i32) -> i32
    where F: Fn(i32) -> i32 {
    f(x)
    }
    // 闭包作为函数参数
    fn use_closure() {
    let add_five = |x: i32| x + 5;
    let result = apply_function(add_five, 10);
    println!("闭包应用结果: {}", result);
    }
    fn main() {
    // 调用简单函数
    let result1 = add(5, 3);
    println!("5 + 3 = {}", result1);
    // 调用多参数函数
    let result2 = multiply(2, 3, 4);
    println!("2 3 4 = {}", result2);
    // 调用无返回值函数
    print_greeting("Rust Programmer");
    // 调用带条件返回的函数
    let result3 = divide(10, 2);
    let result4 = divide(10, 0);
    println!("10 / 2 = {}, 10 / 0 = {}", result3, result4);
    // 调用带默认参数的函数
    greet("Alice", "Hello");
    greet("Bob", "Hi");
    // 调用可变参数函数
    let numbers = [1, 2, 3, 4, 5];
    let total = sum(&numbers);
    println!("数组求和: {}", total);
    // 调用嵌套函数
    outer_function();
    // 调用闭包相关函数
    use_closure();
    // 函数指针
    let add_ptr: fn(i32, i32) -> i32 = add;
    let result5 = add_ptr(10, 20);
    println!("通过函数指针调用: 10 + 20 = {}", result5);
    }
    fn main() {
    // if表达式
    let number = 7;
    if number % 4 == 0 {
    println!("{} 能被4整除", number);
    } else if number % 3 == 0 {
    println!("{} 能被3整除", number);
    } else {
    println!("{} 既不能被4整除也不能被3整除", number);
    }
    // if作为表达式
    let condition = true;
    let value = if condition { 5 } else { 6 };
    println!("if表达式返回值: {}", value);
    // 循环:loop
    let mut count = 0;
    let result = loop {
    count += 1;
    if count == 10 {
    break count * 2; // 从循环中返回值
    }
    };
    println!("loop循环结果: {}", result);
    // 循环:while
    let mut number = 3;
    while number != 0 {
    println!("{}!", number);
    number -= 1;
    }
    println!("LIFTOFF!!!");
    // 循环:for
    let a = [10, 20, 30, 40, 50];
    for element in a.iter() {
    println!("数组元素: {}", element);
    }
    // for循环与范围
    for number in 1..4 {
    println!("范围循环: {}", number);
    }
    // 反向循环
    for number in (1..4).rev() {
    println!("反向循环: {}", number);
    }
    // match表达式
    let coin = Coin::Quarter(UsState::Alabama);
    let value = value_in_cents(coin);
    println!("硬币价值: {} 美分", value);
    // Option<T>的match
    let five = Some(5);
    let six = plus_one(five);
    let none = plus_one(None);
    println!("plus_one(Some(5)) = {:?}", six);
    println!("plus_one(None) = {:?}", none);
    // if let语法糖
    let config_max = Some(3u8);
    if let Some(max) = config_max {
    println!("配置最大值: {}", max);
    }
    // while let语法糖
    let mut stack = Vec::new();
    stack.push(1);
    stack.push(2);
    stack.push(3);
    while let Some(top) = stack.pop() {
    println!("栈顶元素: {}", top);
    }
    // 标签循环
    'outer: for x in 1..=3 {
    for y in 1..=3 {
    if x == 2 && y == 2 {
    break 'outer; // 跳出外层循环
    }
    println!("x: {}, y: {}", x, y);
    }
    }
    }
    // 枚举定义
    #[derive(Debug)]
    enum Coin {
    Penny,
    Nickel,
    Dime,
    Quarter(UsState),
    }
    #[derive(Debug)]
    enum UsState {
    Alabama,
    Alaska,
    // ... 其他州
    }
    // 枚举匹配函数
    fn value_in_cents(coin: Coin) -> u8 {
    match coin {
    Coin::Penny => {
    println!("Lucky penny!");
    1
    },
    Coin::Nickel => 5,
    Coin::Dime => 10,
    Coin::Quarter(state) => {
    println!("来自 {:?} 州的25美分硬币!", state);
    25
    },
    }
    }
    // Option<T>处理函数
    fn plus_one(x: Option<i32>) -> Option<i32> {
    match x {
    None => None,
    Some(i) => Some(i + 1),
    }
    }
    fn main() {
    // ===================== 核心概念:栈/堆与变量地址 =====================
    // 变量表(栈):程序运行时,变量名对应栈上的内存地址,存储"元数据"
    // - 对于基本类型(标量)(5个:布尔、整数、浮点数、元组、字符(char),可以不移交所有权,下文继续用):栈上直接存储值本身
    // - 对于复杂类型(对象)(String、Vec等):栈上存储「指针(指向堆地址)+ 长度 + 容量」,堆上存储实际数据
    // 堆:动态分配的内存,生命周期由所有权系统管理
    // 示例1:打印基本类型(栈上存储)的地址
    let x = 5;
    println!("基本类型x(i32)在栈上的地址: {:p}", &x); // {:p} 格式化输出指针地址
    println!("x的值: {}(栈上直接存储)", x);
    // 示例2:打印String类型的栈地址 + 堆数据地址
    let s = String::from("hello");
    println!("nString变量s在栈上的地址: {:p}", &s); // 栈上的变量地址(存储指针、长度、容量)
    println!("s指向的堆数据起始地址: {:p}", s.as_ptr()); // 堆上实际字符串的地址
    println!("s的长度: {},容量: {}", s.len(), s.capacity());
    // ===================== 所有权规则演示 =====================
    // 规则1:Rust中的每个值都有一个所有者
    let s_owner = String::from("hello"); // s_owner是"hello"的所有者
    println!("ns_owner = {}", s_owner);
    // 规则2:值在任意时刻只能有一个所有者(所有权移动)
    let s1 = String::from("hello");
    println!("移动前:s1栈地址: {:p},堆地址: {:p}", &s1, s1.as_ptr());
    let s2 = s1; // s1的所有权转移(Move)给s2:栈上的元数据(指针、长度、容量)被移动
    // println!("s1 = {}", s1); // 编译错误:s1已失去所有权,变为"无效变量"
    println!("移动后:s2栈地址: {:p},堆地址: {:p}", &s2, s2.as_ptr()); // 堆地址不变,仅栈上元数据转移
    // ===================== 克隆(Clone):深拷贝 =====================
    // 与Move的区别:Clone会复制栈上元数据 + 堆上实际数据,原变量仍有效
    let s_clone_src = String::from("clone demo");
    let s_clone_dst = s_clone_src.clone(); // 显式调用clone,深拷贝
    println!("n克隆示例:");
    println!("s_clone_src栈地址: {:p},堆地址: {:p}", &s_clone_src, s_clone_src.as_ptr());
    println!("s_clone_dst栈地址: {:p},堆地址: {:p}", &s_clone_dst, s_clone_dst.as_ptr());
    println!("s_clone_src = {}, s_clone_dst = {}", s_clone_src, s_clone_dst); // 两者都有效
    // 规则3:当所有者离开作用域,值将被丢弃
    {
    let s_scope = String::from("scope");
    println!("n作用域内: {}", s_scope);
    } // s_scope离开作用域,Rust自动调用drop释放堆内存
    // 基本类型的拷贝(Copy trait):栈上浅拷贝,原变量仍有效
    let x_copy = 5;
    let y_copy = x_copy; // 整数实现Copy,栈上直接拷贝值
    println!("nx_copy = {}, y_copy = {}", x_copy, y_copy);
    // ===================== 引用和借用 =====================
    // 不可变引用:访问值但不获取所有权
    let s_borrow = String::from("hello");
    let len = calculate_length(&s_borrow); // &表示引用(借用)
    println!("n字符串'{}'的长度是{}", s_borrow, len);
    // 可变引用:修改值但不获取所有权
    let mut s_mut = String::from("hello");
    change(&mut s_mut); // &mut表示可变引用
    println!("修改后的字符串: {}", s_mut);
    // ===================== 切片 =====================
    let s_slice = String::from("hello world");
    let hello = &s_slice[0..5]; // 字符串切片(无所有权)
    let world = &s_slice[6..11];
    println!("n切片1: {}, 切片2: {}", hello, world);
    // 数组切片
    let a = [1, 2, 3, 4, 5];
    let slice_arr = &a[1..3];
    println!("数组切片: {:?}", slice_arr);
    // ===================== 函数传递所有权 =====================
    let s_fn = String::from("hello");
    takes_ownership(s_fn);
    // println!("s_fn = {}", s_fn); // 编译错误:所有权已转移
    // 返回值转移所有权
    let s1_fn = gives_ownership();
    let s2_fn = String::from("hello");
    let s3_fn = takes_and_gives_back(s2_fn);
    println!("ns1_fn = {}, s3_fn = {}", s1_fn, s3_fn);
    }
    // 不可变引用函数:借用String,不获取所有权
    fn calculate_length(s: &String) -> usize {
    s.len()
    }
    // 可变引用函数:修改引用的值,不获取所有权
    fn change(some_string: &mut String) {
    some_string.push_str(", world");
    }
    // 函数获取所有权
    fn takes_ownership(some_string: String) {
    println!("n获取所有权: {}", some_string);
    }
    // 函数返回所有权
    fn gives_ownership() -> String {
    let some_string = String::from("hello");
    some_string
    }
    // 函数获取并返回所有权
    fn takes_and_gives_back(a_string: String) -> String {
    a_string
    }
    // 结构体定义
    // 经典结构体(Classic Struct):包含命名字段的结构体
    // 结构体字段可以是不同类型
    struct User {
    active: bool, // 布尔类型字段
    username: String, // 字符串类型字段
    email: String, // 字符串类型字段
    sign_in_count: u64, // 无符号64位整数字段
    }
    // 元组结构体(Tuple Struct):类似于元组的结构体
    // 字段没有名称,只有类型,使用索引访问
    struct Color(i32, i32, i32); // 表示RGB颜色
    struct Point(i32, i32, i32); // 表示三维坐标点
    // 单元结构体(Unit Struct):没有任何字段的结构体
    // 类似于单元类型(),但有自己的类型标识
    struct UnitStruct;
    // 结构体方法定义
    // 结构体的方法在impl(implementation)块中定义
    struct Rectangle {
    width: u32, // 宽度
    height: u32, // 高度
    }
    impl Rectangle {
    // 关联函数(Associated Function)- 静态方法
    // 关联函数不接收self参数,使用结构体名调用
    // 通常用于创建结构体实例
    fn square(size: u32) -> Rectangle {
    Rectangle { width: size, height: size }
    }
    // 实例方法(Instance Method)
    // 方法接收&self参数,表示对实例的不可变引用
    // 用于访问实例的字段和行为
    fn area(&self) -> u32 {
    self.width * self.height // 计算矩形面积
    }
    // 带参数的方法
    // 方法可以接收其他参数
    fn can_hold(&self, other: &Rectangle) -> bool {
    // 判断当前矩形是否能容纳另一个矩形
    self.width > other.width && self.height > other.height
    }
    // 可变方法(Mutable Method)
    // 方法接收&mut self参数,表示对实例的可变引用
    // 可以修改实例的字段
    fn double_size(&mut self) {
    self.width *= 2; // 宽度加倍
    self.height *= 2; // 高度加倍
    }
    }
    // 结构体方法重载
    // Rust不支持传统意义上的方法重载(同名方法不同参数)
    // 但可以通过不同的方法名实现类似功能
    struct Counter {
    count: u32, // 计数器值
    }
    impl Counter {
    // 构造函数(通常命名为new)
    fn new() -> Counter {
    Counter { count: 0 }
    }
    // 增加1的方法
    fn increment(&mut self) {
    self.count += 1;
    }
    // 增加指定数量的方法
    fn increment_by(&mut self, amount: u32) {
    self.count += amount;
    }
    // 获取当前值的方法
    fn get_count(&self) -> u32 {
    self.count
    }
    }
    // 结构体组合
    // 结构体可以包含其他结构体作为字段,实现组合
    struct Address {
    street: String, // 街道
    city: String, // 城市
    zip_code: String, // 邮政编码
    }
    struct Person {
    name: String, // 姓名
    age: u32, // 年龄
    address: Address, // 地址(结构体字段)
    }
    impl Person {
    // 构造函数
    fn new(name: String, age: u32, address: Address) -> Person {
    // 使用字段初始化简写语法
    Person { name, age, address }
    }
    // 打印个人信息的方法
    fn print_info(&self) {
    println!("姓名: {}", self.name);
    println!("年龄: {}", self.age);
    println!("地址: {} {}, {}",
    self.address.street,
    }
    }
    fn main() {
    // 创建结构体实例
    // 使用结构体名和字段初始化语法
    let user1 = User {
    active: true,
    username: String::from("someone123"),
    email: String::from("someone@example.com"),
    sign_in_count: 1,
    };
    // 注意这里没有mut,不可以直接更改,例如user1.active = xxx;
    // 访问结构体字段
    println!("用户名: {}", user1.username);
    println!("邮箱: {}", user1.email);
    // 结构体更新语法
    // 使用..语法可以从其他实例复制字段
    let user2 = User {
    email: String::from("another@example.com"), // 新的邮箱地址
    ..user1 // 复制user1的其他字段
    };
    println!("user2 用户名: {}", user2.username); // 来自user1
    println!("user2 邮箱: {}", user2.email); // 新的邮箱
    // 元组结构体
    // 元组结构体使用类似元组的语法创建
    let black = Color(0, 0, 0); // 黑色
    let origin = Point(0, 0, 0); // 原点坐标
    // 访问元组结构体字段(使用索引)
    println!("黑色RGB: {}, {}, {}", black.0, black.1, black.2);
    println!("原点坐标: ({}, {}, {})", origin.0, origin.1, origin.2);
    // 单元结构体
    // 单元结构体没有字段,创建时不需要参数
    let unit = UnitStruct;
    // 结构体方法调用
    // 实例方法使用点语法调用
    let rect1 = Rectangle { width: 30, height: 50 };
    println!("矩形面积: {}", rect1.area()); // 调用area方法
    // 关联函数调用
    // 关联函数使用::语法调用
    let square = Rectangle::square(20); // 调用square关联函数
    println!("正方形面积: {}", square.area());
    // 方法参数
    let rect2 = Rectangle { width: 10, height: 40 };
    let rect3 = Rectangle { width: 60, height: 45 };
    println!("rect1能容纳rect2吗? {}", rect1.can_hold(&rect2));
    println!("rect1能容纳rect3吗? {}", rect1.can_hold(&rect3));
    // 可变方法
    // 要调用可变方法,实例必须是可变的
    let mut rect4 = Rectangle { width: 5, height: 5 };
    println!("修改前面积: {}", rect4.area());
    rect4.double_size(); // 调用可变方法
    println!("修改后面积: {}", rect4.area());
    // 方法重载示例
    let mut counter = Counter::new(); // 创建计数器
    counter.increment(); // 增加1
    counter.increment_by(5); // 增加5
    println!("计数器值: {}", counter.get_count());
    // 结构体组合
    let address = Address {
    street: String::from("123 Main St"),
    city: String::from("Anytown"),
    zip_code: String::from("12345"),
    };
    let person = Person::new(
    String::from("John Doe"),
    30,
    address // address的所有权转移给person
    );
    person.print_info(); // 调用print_info方法
    }
    // 简单枚举
    enum IpAddrKind {
    V4,
    V6,
    }
    // 带数据的枚举
    enum IpAddr {
    V4(u8, u8, u8, u8),
    V6(String),
    }
    // 枚举变体可以有不同类型的数据
    enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
    }
    // 为枚举定义方法
    impl Message {
    fn call(&self) {
    match self {
    Message::Quit => println!("Quit message received"),
    Message::Move { x, y } => println!("Move to ({}, {})", x, y),
    Message::Write(text) => println!("Write message: {}", text),
    Message::ChangeColor(r, g, b) => println!("Change color to RGB({}, {}, {})", r, g, b),
    }
    }
    }
    // Option枚举(标准库提供)
    // enum Option<T> {
    // Some(T),
    // None,
    // }
    // 复杂枚举示例
    enum WebEvent {
    PageLoad,
    PageUnload,
    KeyPress(char),
    Paste(String),
    Click { x: i64, y: i64 },
    }
    // 模式匹配函数
    fn inspect(event: WebEvent) {
    match event {
    WebEvent::PageLoad => println!("页面加载"),
    WebEvent::PageUnload => println!("页面卸载"),
    WebEvent::KeyPress(c) => println!("按键: '{}'" , c),
    WebEvent::Paste(s) => println!("粘贴内容: {}", s),
    WebEvent::Click { x, y } => println!("点击位置: ({}, {})", x, y),
    }
    }
    // 枚举组合
    enum Shape {
    Circle(f64), // 半径
    Rectangle(f64, f64), // 长和宽
    Triangle(f64, f64, f64), // 三条边
    }
    impl Shape {
    fn area(&self) -> f64 {
    match self {
    Shape::Circle(r) => std::f64::consts::PI r r,
    Shape::Rectangle(w, h) => w * h,
    Shape::Triangle(a, b, c) => {
    // 使用海伦公式计算三角形面积
    let s = (a + b + c) / 2.0;
    (s (s - a) (s - b) * (s - c)).sqrt()
    }
    }
    }
    }
    // if let 语法糖
    fn handle_option(value: Option<i32>) {
    if let Some(x) = value {
    println!("获取到Some值: {}", x);
    } else {
    println!("获取到None值");
    }
    }
    // while let 语法糖
    fn process_values() {
    let mut stack = Vec::new();
    stack.push(1);
    stack.push(2);
    stack.push(3);
    while let Some(top) = stack.pop() {
    println!("处理值: {}", top);
    }
    }
    // 模式匹配中的通配符
    fn match_with_wildcard(x: u8) {
    match x {
    1 => println!("one"),
    2 => println!("two"),
    3 => println!("three"),
    _ => println!("其他数字"), // 通配符
    }
    }
    // 模式匹配中的范围
    fn match_with_range(x: i32) {
    match x {
    1..=5 => println!("1到5之间"),
    6..=10 => println!("6到10之间"),
    _ => println!("超出范围"),
    }
    }
    fn main() {
    // 简单枚举使用
    let four = IpAddrKind::V4;
    let six = IpAddrKind::V6;
    // 带数据的枚举
    let home = IpAddr::V4(127, 0, 0, 1);
    let loopback = IpAddr::V6(String::from("::1"));
    // 枚举方法调用
    let quit_msg = Message::Quit;
    let move_msg = Message::Move { x: 10, y: 20 };
    let write_msg = Message::Write(String::from("Hello, Rust!"));
    let color_msg = Message::ChangeColor(255, 0, 0);
    quit_msg.call();
    move_msg.call();
    write_msg.call();
    color_msg.call();
    // Option枚举使用
    // Option里要么有值Some, 要么为None
    let some_number = Some(5);
    let some_string = Some("a string");
    let absent_number: Option<i32> = None;
    println!("some_number: {:?}", some_number);
    println!("some_string: {:?}", some_string);
    println!("absent_number: {:?}", absent_number);
    match some_number {
    Some(x) => println!("Matched:{}", x),
    None => println!("No value"),
    }
    // 复杂枚举模式匹配
    let pressed = WebEvent::KeyPress('x');
    let pasted = WebEvent::Paste("my text".to_owned());
    let click = WebEvent::Click { x: 20, y: 80 };
    inspect(pressed);
    inspect(pasted);
    inspect(click);
    // 枚举组合计算
    let circle = Shape::Circle(5.0);
    let rectangle = Shape::Rectangle(10.0, 20.0);
    let triangle = Shape::Triangle(3.0, 4.0, 5.0);
    println!("圆形面积: {}", circle.area());
    println!("矩形面积: {}", rectangle.area());
    println!("三角形面积: {}", triangle.area());
    // if let 使用
    handle_option(Some(42));
    handle_option(None);
    // while let 使用
    process_values();
    // 通配符匹配
    match_with_wildcard(3);
    match_with_wildcard(5);
    // 范围匹配
    match_with_range(3);
    match_with_range(8);
    match_with_range(15);
    }
    use std::collections::{HashMap, HashSet, BTreeMap, BTreeSet};
    fn main() {
    // Vector(动态数组)
    let mut v = Vec::new();
    v.push(1);
    v.push(2);
    v.push(3);
    println!("Vector: {:?}", v);
    println!("Vector长度: {}", v.len());
    println!("Vector容量: {}", v.capacity());
    // 访问Vector元素
    let first = &v[0];
    println!("第一个元素: {}", first);
    match v.get(1) {
    Some(second) => println!("第二个元素: {}", second),
    None => println!("没有第二个元素"),
    }
    // 遍历Vector
    println!("遍历Vector:");
    for i in &v {
    println!("{}", i);
    }
    // 修改遍历中的元素
    for i in &mut v {
    i = 2;
    }
    println!("修改后的Vector: {:?}", v);
    // String(字符串)
    let mut s = String::new();
    s.push_str("Hello");
    s.push(' ');
    s.push_str("World!");
    println!("nString: {}", s);
    println!("字符串长度: {}", s.len());
    println!("是否为空: {}", s.is_empty());
    // 字符串拼接
    let s1 = String::from("Hello, ");
    let s2 = String::from("Rust!");
    let s3 = s1 + &s2; // s1的所有权被移动,不能再使用
    println!("拼接后的字符串: {}", s3);
    // 格式化字符串
    let name = "Alice";
    let age = 30;
    let formatted = format!("姓名: {}, 年龄: {}", name, age);
    println!("格式化字符串: {}", formatted);
    // 字符串切片
    let hello = "Здравствуйте";
    let s = &hello[0..4];
    println!("字符串切片: {}", s);
    // HashMap(哈希映射)
    let mut scores = HashMap::new();
    scores.insert(String::from("Blue"), 10); // k, v
    scores.insert(String::from("Yellow"), 50); // k, v
    println!("nHashMap: {:?}", scores);
    // 访问HashMap值
    let team_name = String::from("Blue");
    let score = scores.get(&team_name);
    match score {
    Some(s) => println!("Blue队得分: {}", s),
    None => println!("没有找到Blue队"),
    }
    // 遍历HashMap
    println!("遍历HashMap:");
    for (key, value) in &scores {
    println!("{}: {}", key, value);
    }
    // 更新HashMap
    scores.insert(String::from("Blue"), 25); // 覆盖值
    println!("更新后的HashMap: {:?}", scores);
    // 只在键不存在时插入
    scores.entry(String::from("Red")).or_insert(30);
    scores.entry(String::from("Blue")).or_insert(50);
    println!("插入后的HashMap: {:?}", scores);
    // HashSet(哈希集合)
    let mut set = HashSet::new();
    set.insert(1);
    set.insert(2);
    set.insert(3);
    set.insert(2); // 重复元素不会被插入
    println!("nHashSet: {:?}", set);
    println!("集合大小: {}", set.len());
    println!("是否包含2: {}", set.contains(&2));
    // 集合操作
    let a: HashSet<_> = vec![1, 2, 3].into_iter().collect();
    let b: HashSet<_> = vec![2, 3, 4].into_iter().collect();
    println!("交集: {:?}", a.intersection(&b));
    println!("并集: {:?}", a.union(&b));
    println!("差集: {:?}", a.difference(&b));
    // BTreeMap(有序映射)
    let mut tree_map = BTreeMap::new();
    tree_map.insert(3, "three");
    tree_map.insert(1, "one");
    tree_map.insert(2, "two");
    println!("nBTreeMap: {:?}", tree_map);
    // BTreeSet(有序集合)
    let mut tree_set = BTreeSet::new();
    tree_set.insert(3);
    tree_set.insert(1);
    tree_set.insert(2);
    println!("BTreeSet: {:?}", tree_set);
    // 更多集合操作
    let mut v = vec![1, 2, 3, 4, 5];
    // 排序
    v.sort();
    println!("n排序后的Vector: {:?}", v);
    // 反转
    v.reverse();
    println!("反转后的Vector: {:?}", v);
    // 过滤
    let filtered: Vec<_> = v.iter().filter(|&&x| x > 2).collect();
    println!("过滤后的Vector: {:?}", filtered);
    // 映射
    let mapped: Vec<_> = v.iter().map(|&x| x * 2).collect();
    println!("映射后的Vector: {:?}", mapped);
    // 求和
    let sum: i32 = v.iter().sum();
    println!("Vector元素总和: {}", sum);
    }
    // 声明模块
    mod front_of_house {
    // 嵌套模块
    pub mod hosting {
    pub fn add_to_waitlist() {
    println!("添加到等待列表");
    }
    fn seat_at_table() {
    println!("安排座位");
    }
    }
    // 嵌套模块
    mod serving {
    pub fn take_order() {
    println!("接受订单");
    }
    pub fn serve_order() {
    println!("提供服务");
    }
    pub fn take_payment() {
    println!("收款");
    }
    }
    }
    // 导入模块
    use crate::front_of_house::hosting; // 试用这个里面的 这个模块...
    use crate::front_of_house::serving::{serve_order, take_payment}; // 使用这个模块里的这个模块里的 这个和这个方法。
    // 嵌套模块
    mod back_of_house {
    pub struct Breakfast {
    pub toast: String,
    seasonal_fruit: String,
    }
    impl Breakfast {
    pub fn summer(toast: &str) -> Breakfast {
    Breakfast {
    toast: String::from(toast),
    seasonal_fruit: String::from("桃子"),
    }
    }
    }
    mod kitchen {
    pub fn cook_order() {
    println!("烹饪订单");
    }
    }
    }
    use crate::back_of_house::Breakfast;
    use crate::back_of_house::kitchen;
    // 外部包导入示例
    // extern crate rand;
    // use rand::Rng;
    // 模块路径
    fn deliver_order() {
    // 绝对路径
    crate::front_of_house::hosting::add_to_waitlist();
    // 相对路径
    front_of_house::serving::take_order();
    }
    fn main() {
    println!("=== 包和模块示例 ===n");
    // 使用导入的模块
    hosting::add_to_waitlist();
    serve_order();
    take_payment();
    // 使用结构体
    let mut meal = Breakfast::summer("全麦");
    println!("n早餐吐司: {}", meal.toast);
    // println!("季节水果: {}", meal.seasonal_fruit); // 这会导致编译错误,因为seasonal_fruit是私有的
    // 修改公共字段
    meal.toast = String::from("白面包");
    println!("修改后的吐司: {}", meal.toast);
    // 使用嵌套模块
    kitchen::cook_order();
    // 使用模块路径
    deliver_order();
    // 包结构说明
    println!("n=== 包结构说明 ===");
    println!("Rust包结构:");
    println!("my_crate/");
    println!("├── Cargo.toml");
    println!("├── Cargo.lock");
    println!("└── src/");
    println!(" ├── lib.rs # 库包的根文件");
    println!(" ├── main.rs # 二进制包的根文件");
    println!(" ├── module1.rs # 模块文件");
    println!(" └── module2/ # 模块目录");
    println!(" └── mod.rs # 模块目录的根文件");
    // 模块可见性规则
    println!("n=== 模块可见性规则 ===");
    println!("1. 默认情况下,模块中的项是私有的");
    println!("2. 使用pub关键字可以将项设为公共的");
    println!("3. 子模块可以访问父模块中的项");
    println!("4. 父模块不能访问子模块中的私有项");
    println!("5. 使用use关键字可以简化模块路径");
    }
    // 模块文件导入示例(注释掉的代码展示如何导入其他文件中的模块)
    // mod module1; // 导入module1.rs文件
    // mod module2; // 导入module2/mod.rs文件
    use std::fs::File;
    use std::io::{self, Read};
    use std::num::ParseIntError;
    // Result枚举定义(标准库提供)
    // enum Result<T, E> {
    // Ok(T),
    // Err(E),
    // }
    // 简单错误处理
    fn read_username_from_file() -> Result<String, io::Error> {
    let mut f = File::open("hello.txt")?;
    let mut s = String::new();
    f.read_to_string(&mut s)?;
    Ok(s)
    }
    // 更简洁的版本
    fn read_username_short() -> Result<String, io::Error> {
    fs::read_to_string("hello.txt")
    }
    // 错误传播
    fn parse_number(s: &str) -> Result<i32, ParseIntError> {
    s.parse::<i32>()
    }
    // 组合多个错误
    fn multiply_two_numbers(s1: &str, s2: &str) -> Result<i32, ParseIntError> {
    let n1 = s1.parse::<i32>()?;
    let n2 = s2.parse::<i32>()?;
    Ok(n1 * n2)
    }
    // 自定义错误类型
    #[derive(Debug)]
    enum CustomError {
    IoError(io::Error),
    ParseError(ParseIntError),
    InvalidInput(String),
    }
    impl From<io::Error> for CustomError {
    fn from(err: io::Error) -> Self {
    CustomError::IoError(err)
    }
    }
    impl From<ParseIntError> for CustomError {
    fn from(err: ParseIntError) -> Self {
    CustomError::ParseError(err)
    }
    }
    // 如果有 内容,则返回一个空的OK , 如果没有,则返回错误
    fn complex_operation() -> Result<(), CustomError> {
    let mut file = File::open("data.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    let number: i32 = contents.trim().parse()?;
    if number < 0 {
    return Err(CustomError::InvalidInput(
    "数字不能为负数".to_string()
    ));
    }
    Ok(())
    }
    // panic!宏(不可恢复错误)
    fn panic_example() {
    // 故意触发panic
    let v = vec![1, 2, 3];
    v[99]; // 索引越界,触发panic
    }
    // 错误处理策略
    fn error_handling_strategies() {
    // 1. 传播错误(最常见)
    let result = read_username_from_file();
    match result {
    Ok(username) => println!("用户名: {}", username),
    Err(e) => println!("读取文件失败: {}", e),
    }
    // 2. 匹配不同的错误类型
    let file_result = File::open("hello.txt");
    match file_result {
    Ok(file) => println!("文件打开成功"),
    Err(error) => match error.kind() {
    io::ErrorKind::NotFound => println!("文件未找到"),
    io::ErrorKind::PermissionDenied => println!("权限不足"),
    _ => println!("其他错误: {}", error),
    },
    }
    // 3. 使用unwrap和expect(快速原型开发)
    let file = File::open("hello.txt").unwrap(); // 这里使用了unwrap如果失败则发生panic(崩溃)
    let file = File::open("hello.txt")
    .expect("打开hello.txt文件失败"); // 提供自定义panic消息
    // 4. 静默失败(不推荐)
    let _ = File::open("hello.txt");
    }
    // 错误链
    fn error_chain() -> Result<(), Box<dyn std::error::Error>> {
    let mut file = File::open("chain.txt")?;
    let mut contents = String::new();
    file.read_to_string(&mut contents)?;
    let number: i32 = contents.trim().parse()?;
    println!("读取的数字: {}", number);
    Ok(())
    }
    fn main() {
    println!("=== Rust错误处理示例 ===n");
    // 简单错误处理 (可恢复错误)
    match read_username_from_file() {
    Ok(username) => println!("读取到的用户名: {}", username),
    Err(e) => println!("读取文件错误: {}", e),
    }
    // 数字解析错误处理
    let result = multiply_two_numbers("42", "2");
    match result {
    Ok(product) => println!("乘法结果: {}", product),
    Err(e) => println!("解析错误: {}", e),
    }
    let result = multiply_two_numbers("42", "abc");
    match result {
    Ok(product) => println!("乘法结果: {}", product),
    Err(e) => println!("解析错误: {}", e),
    }
    // 自定义错误类型
    match complex_operation() {
    Ok(()) => println!("复杂操作成功"),
    Err(e) => println!("复杂操作失败: {:?}", e),
    }
    // 错误链
    match error_chain() {
    Ok(()) => println!("错误链操作成功"),
    Err(e) => println!("错误链操作失败: {}", e),
    }
    // 错误处理总结
    println!("n=== 错误处理总结 ===");
    println!("1. Result<T, E> 用于可恢复错误");
    println!("2. panic! 用于不可恢复错误");
    println!("3. ? 操作符用于传播错误");
    println!("4. 可以定义自定义错误类型");
    println!("5. 错误处理策略包括:传播、匹配、unwrap/expect、静默失败");
    }
    // 泛型函数
    fn largest<T: PartialOrd + Copy>(list: &[T]) -> T {
    let mut largest = list[0];
    for &item in list.iter() {
    if item > largest {
    largest = item;
    }
    }
    largest
    }
    // 泛型结构体
    struct Point<T> {
    x: T;
    y: T,
    }
    // 为泛型结构体实现方法
    impl<T> Point<T> {
    fn x(&self) -> &T {
    &self.x
    }
    fn y(&self) -> &T {
    &self.y
    }
    }
    // 为特定类型实现方法
    impl Point<f32> {
    fn distance_from_origin(&self) -> f32 {
    (self.x.powi(2) + self.y.powi(2)).sqrt()
    }
    }
    // 多参数泛型结构体
    struct Pair<T, U> {
    x: T,
    y: U,
    }
    impl<T, U> Pair<T, U> {
    fn new(x: T, y: U) -> Self {
    Pair { x, y }
    }
    fn components(&self) -> (&T, &U) {
    (&self.x, &self.y)
    }
    }
    // 泛型枚举
    enum Option<T> {
    Some(T),
    None,
    }
    enum Result<T, E> {
    Ok(T),
    Err(E),
    }
    // 泛型约束
    fn print_if_display<T: std::fmt::Display>(item: T) {
    println!("{}", item);
    }
    // 多重约束
    fn compare_and_print<T: std::fmt::Display + PartialOrd>(a: T, b: T) {
    if a > b {
    println!("{} 大于 {}", a, b);
    } else if a < b {
    println!("{} 小于 {}", a, b);
    } else {
    println!("{} 等于 {}", a, b);
    }
    }
    // where子句(更清晰的约束语法)
    fn some_function<T, U>(t: T, u: U) -> i32
    where
    T: std::fmt::Display + Clone,
    U: std::fmt::Debug + Clone,
    {
    println!("T: {}, U: {:?}", t, u);
    42
    }
    // 泛型返回类型
    fn identity<T>(x: T) -> T {
    x
    }
    // 泛型集合操作
    fn find_first<T: PartialEq>(list: &[T], target: &T) -> Option<usize> {
    for (index, item) in list.iter().enumerate() {
    if item == target {
    return Some(index);
    }
    }
    None
    }
    fn main() {
    println!("=== Rust泛型示例 ===n");
    // 泛型函数使用
    let numbers = vec![34, 50, 25, 100, 65];
    let result = largest(&numbers);
    println!("最大的数字: {}", result);
    let chars = vec!['y', 'm', 'a', 'q'];
    let result = largest(&chars);
    println!("最大的字符: {}", result);
    // 泛型结构体
    let integer_point = Point { x: 5, y: 10 };
    let float_point = Point { x: 1.0, y: 4.0 };
    println!("n整数点: ({}, {})", integer_point.x(), integer_point.y());
    println!("浮点点点: ({}, {})", float_point.x(), float_point.y());
    println!("浮点点距离原点: {}", float_point.distance_from_origin());
    // 多参数泛型
    let pair = Pair::new(10, "hello");
    let (x, y) = pair.components();
    println!("nPair: x={}, y={}", x, y);
    // 泛型约束
    print_if_display(42);
    print_if_display("hello");
    // print_if_display(true); // 错误,bool不实现Display trait
    compare_and_print(10, 20);
    compare_and_print(3.14, 2.71);
    compare_and_print("apple", "banana");
    // where子句
    some_function(42, "hello");
    // 泛型返回类型
    let num = identity(42);
    let text = identity("hello");
    println!("nidentity(42) = {}", num);
    println!("identity("hello") = {}", text);
    // 泛型集合操作
    let numbers = vec![1, 2, 3, 4, 5];
    let index = find_first(&numbers, &3);
    println!("n查找3的位置: {:?}", index);
    let fruits = vec!["apple", "banana", "cherry"];
    let index = find_first(&fruits, &"banana");
    println!("查找"banana"的位置: {:?}", index);
    // 泛型总结
    println!("n=== 泛型总结 ===");
    println!("1. 泛型允许编写不特定于具体类型的代码");
    println!("2. 泛型使用<T>语法定义类型参数");
    println!("3. 可以为泛型类型添加约束(trait bounds)");
    println!("4. where子句提供更清晰的约束语法");
    println!("5. 泛型在编译时会进行单态化,不影响运行时性能");
    println!("6. 标准库广泛使用泛型:Vec<T>, Option<T>, Result<T, E>等");
    }
    // 12_traits_detailed.rs - Rust Trait详解(详细注释版)
    // Trait定义
    // Trait(特征)是Rust中定义共享行为的方式,类似于其他语言中的接口(Interface)
    // Trait定义了一组方法的签名,类型可以实现这些方法来提供特定的行为
    trait Summary {
    // 抽象方法(Abstract Method)
    // 没有默认实现的方法,实现Trait的类型必须提供具体实现
    fn summarize(&self) -> String;
    // 默认实现方法(Default Method Implementation)
    // 提供了默认实现的方法,实现Trait的类型可以选择覆盖或使用默认实现
    fn summarize_author(&self) -> String {
    String::from("Unknown author") // 默认返回"Unknown author"
    }
    // 调用其他方法的默认方法
    // 默认方法可以调用Trait中的其他方法,包括抽象方法
    fn summarize_with_author(&self) -> String {
    format!("{} - {}", self.summarize(), self.summarize_author())
    }
    }
    // 为类型实现Trait
    // 结构体定义 - 新闻文章
    struct NewsArticle {
    headline: String, // 标题
    location: String, // 位置
    author: String, // 作者
    content: String, // 内容
    }
    // 为NewsArticle实现Summary Trait
    // 使用impl关键字,后面跟Trait名称,然后是for关键字和类型名称
    impl Summary for NewsArticle {
    // 实现抽象方法summarize
    // 必须提供具体实现,因为Trait中没有默认实现
    fn summarize(&self) -> String {
    format!("{}, by {} ({})", self.headline, self.author, self.location)
    }
    // 覆盖默认方法summarize_author
    // 可以选择覆盖默认方法,提供自定义实现
    fn summarize_author(&self) -> String {
    format!("@{}", self.author) // 返回带有@符号的作者名
    }
    }
    // 结构体定义 - 推文
    struct Tweet {
    username: String, // 用户名
    content: String, // 内容
    reply: bool, // 是否是回复
    retweet: bool, // 是否是转发
    }
    // 为Tweet实现Summary Trait
    impl Summary for Tweet {
    // 只实现抽象方法summarize,使用默认的summarize_author
    // 对于有默认实现的方法,可以选择不覆盖
    fn summarize(&self) -> String {
    format!("{}: {}", self.username, self.content)
    }
    }
    // Trait作为参数
    // 使用impl Trait语法,函数可以接受任何实现了指定Trait的类型
    // 这是一种语法糖,等价于泛型Trait约束
    fn notify(item: &impl Summary) {
    println!("Breaking news! {}", item.summarize());
    }
    // Trait约束语法(Trait Bound Syntax)
    // 与impl Trait语法等价,但更明确地使用泛型参数
    // 当需要在多个地方引用相同的泛型类型时,这种语法更有用
    fn notify_with_constraint<T: Summary>(item: &T) {
    println!("Breaking news! {}", item.summarize());
    }
    // 多个Trait约束
    // 可以指定类型需要实现多个Trait,使用+符号分隔
    fn notify_multiple<T: Summary + std::fmt::Display>(item: &T) {
    println!("News: {} - {}", item, item.summarize());
    }
    // where子句(Where Clause)
    // 当有多个泛型参数和Trait约束时,where子句提供更清晰的语法
    // 特别是当约束比较复杂时,where子句比在函数签名中使用+符号更易读
    fn some_function<T, U>(t: &T, u: &U) -> i32
    where
    T: Summary + Clone, // T需要实现Summary和Clone Trait
    U: std::fmt::Debug + Clone, // U需要实现Debug和Clone Trait
    {
    println!("T: {}", t.summarize());
    println!("U: {:?}", u);
    42 // 返回一个整数
    }
    // Trait作为返回类型
    // 函数可以返回实现了指定Trait的类型,使用impl Trait语法
    // 注意:这种语法只能返回一种具体类型,即使有多个类型实现了相同的Trait
    fn returns_summarizable() -> impl Summary {
    Tweet {
    username: String::from("horse_ebooks"),
    content: String::from("of course, as you probably already know, people"),
    reply: false,
    retweet: false,
    }
    }
    // 条件实现方法(Conditional Implementation)
    // 可以为满足特定Trait约束的泛型类型实现方法
    struct Pair<T> {
    x: T,
    y: T,
    }
    // 为所有Pair<T>实现new方法
    // 这个实现对任何类型T都有效
    impl<T> Pair<T> {
    fn new(x: T, y: T) -> Self {
    Pair { x, y }
    }
    }
    // 只为实现了Display和PartialOrd的Pair<T>实现cmp_display方法
    // 这个实现只对满足Trait约束的类型T有效
    impl<T: std::fmt::Display + PartialOrd> Pair<T> {
    fn cmp_display(&self) {
    if self.x >= self.y {
    println!("The largest member is x = {}", self.x);
    } else {
    println!("The largest member is y = {}", self.y);
    }
    }
    }
    // 为其他类型实现Trait(孤儿规则)
    // 孤儿规则(Orphan Rule):只能为本地类型实现外部Trait,或者为外部类型实现本地Trait
    // 这里为Tweet实现标准库的Display Trait
    impl std::fmt::Display for Tweet {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
    write!(f, "{}: {}", self.username, self.content)
    }
    }
    // 派生Trait(Derived Trait)
    // 使用#[derive]属性可以自动实现一些标准Trait
    // 可以派生的Trait包括:Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy等
    #[derive(Debug, PartialEq, Clone)]
    struct Point {
    x: i32,
    y: i32,
    }
    // 运算符Trait(Operator Trait)
    // 标准库提供了一系列运算符Trait,实现这些Trait可以重载运算符
    use std::ops::Add;
    // 为Point实现Add Trait,重载+运算符
    impl Add for Point {
    type Output = Point; // 关联类型,指定加法的输出类型
    fn add(self, other: Point) -> Point {
    Point {
    x: self.x + other.x,
    y: self.y + other.y,
    }
    }
    }
    // 关联类型(Associated Types)
    // Trait可以定义关联类型,关联类型是Trait定义的一部分
    // 关联类型指定了Trait中某些方法会使用的类型
    trait Iterator {
    type Item; // 关联类型,指定迭代器产生的元素类型
    fn next(&mut self) -> Option<Self::Item>;
    }
    struct Counter {
    count: u32,
    }
    impl Counter {
    fn new() -> Counter {
    Counter { count: 0 }
    }
    }
    // 为Counter实现Iterator Trait
    impl Iterator for Counter {
    type Item = u32; // 指定关联类型为u32
    fn next(&mut self) -> Option<Self::Item> {
    if self.count < 5 {
    self.count += 1;
    Some(self.count)
    } else {
    None
    }
    }
    }
    fn main() {
    println!("=== Rust Trait示例 ===n");
    // Trait实现
    let tweet = Tweet {
    username: String::from("horse_ebooks"),
    content: String::from("of course, as you probably already know, people"),
    reply: false,
    retweet: false,
    };
    let article = NewsArticle {
    headline: String::from("Penguins win the Stanley Cup Championship!"),
    location: String::from("Pittsburgh, PA, USA"),
    author: String::from("Iceburgh"),
    content: String::from("The Pittsburgh Penguins once again are the best\
    hockey team in the NHL."),
    };
    println!("Tweet summary: {}", tweet.summarize());
    println!("Article summary: {}", article.summarize());
    println!("Tweet with author: {}", tweet.summarize_with_author());
    println!("Article with author: {}", article.summarize_with_author());
    // Trait作为参数
    notify(&tweet);
    notify(&article);
    // 多个Trait约束
    notify_multiple(&tweet);
    // Trait作为返回类型
    let item = returns_summarizable();
    println!("n返回的Trait对象: {}", item.summarize());
    // 条件实现方法
    let pair = Pair::new(1, 2);
    pair.cmp_display();
    // 派生Trait
    let p1 = Point { x: 1, y: 2 };
    let p2 = Point { x: 1, y: 2 };
    let p3 = Point { x: 3, y: 4 };
    println!("nPoint p1: {:?}", p1); // 使用Debug Trait
    println!("p1 == p2: {}", p1 == p2); // 使用PartialEq Trait
    println!("p1 == p3: {}", p1 == p3);
    // 运算符Trait
    let p4 = p1 + p2; // 使用Add Trait
    println!("p1 + p2 = {:?}", p4);
    // 关联类型
    let mut counter = Counter::new();
    println!("nCounter迭代:");
    while let Some(count) = counter.next() { // 使用Iterator Trait
    println!("{}", count);
    }
    // Trait总结
    println!("n=== Trait总结 ===");
    println!("1. Trait定义共享行为");
    println!("2. 可以为类型实现Trait");
    println!("3. Trait可以作为参数和返回类型");
    println!("4. 支持多个Trait约束");
    println!("5. 支持条件实现方法");
    println!("6. 可以派生标准Trait");
    println!("7. 支持运算符重载");
    println!("8. 有关联类型的Trait");
    }
    // 简单生命周期示例
    fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() {
    x
    } else {
    y
    }
    }
    // 生命周期省略规则
    // 规则1:每个参数的生命周期成为独立的生命周期参数
    // 规则2:如果只有一个输入生命周期参数,它被赋予所有输出生命周期参数
    // 规则3:如果有多个输入生命周期参数,且其中一个是&self或&mut self,
    // 那么self的生命周期被赋予所有输出生命周期参数
    // 结构体中的生命周期
    struct ImportantExcerpt<'a> {
    part: &'a str,
    }
    impl<'a> ImportantExcerpt<'a> {
    // 方法中的生命周期
    fn level(&self) -> i32 {
    3
    }
    // 带生命周期的方法
    fn announce_and_return_part(&self, announcement: &str) -> &str {
    println!("Attention please: {}", announcement);
    self.part
    }
    }
    // 静态生命周期
    fn static_lifetime() {
    let s: &'static str = "I have a static lifetime.";
    println!("静态字符串: {}", s);
    }
    // 多个生命周期参数
    fn longest_with_an_announcement<'a, T>(
    x: &'a str,
    y: &'a str,
    ann: T,
    ) -> &'a str
    where
    T: std::fmt::Display,
    {
    println!("Announcement! {}", ann);
    if x.len() > y.len() {
    x
    } else {
    y
    }
    }
    // 生命周期与泛型和Trait结合
    fn complex_function<'a, T>(x: &'a T, y: &'a T) -> &'a T
    where
    T: std::fmt::Display + PartialOrd,
    {
    if x > y {
    x
    } else {
    y
    }
    }
    // 生命周期边界
    fn lifetime_bounds<'a, T: 'a>(x: &'a T) -> &'a T {
    x
    }
    // 省略生命周期的常见模式
    fn first_word(s: &str) -> &str {
    let bytes = s.as_bytes();
    for (i, &item) in bytes.iter().enumerate() {
    if item == b' ' {
    return &s[0..i];
    }
    }
    &s[..]
    }
    // 结构体中的多个生命周期
    struct MultiLifetime<'a, 'b> {
    part1: &'a str,
    part2: &'b str,
    }
    // 生命周期与闭包
    fn lifetime_with_closure() {
    let x = 5;
    let equal_to_x = |z: i32| z == x;
    let y = 5;
    assert!(equal_to_x(y));
    }
    fn main() {
    println!("=== Rust生命周期示例 ===n");
    // 简单生命周期函数
    let string1 = String::from("abcd");
    let string2 = "xyz";
    let result = longest(string1.as_str(), string2);
    println!("较长的字符串: {}", result);
    // 结构体中的生命周期
    let novel = String::from("Call me Ishmael. Some years ago...");
    let first_sentence = novel.split('.').next().expect("Could not find a '.'");
    let i = ImportantExcerpt {
    part: first_sentence,
    };
    println!("n结构体中的引用: {}", i.part);
    println!("方法返回的引用: {}", i.announce_and_return_part("Listen!"));
    // 静态生命周期
    static_lifetime();
    // 多个生命周期参数
    let string3 = String::from("long string is long");
    let result = longest_with_an_announcement(
    string1.as_str(),
    string3.as_str(),
    "Today we're announcing the longest string!",
    );
    println!("n带公告的较长字符串: {}", result);
    // 省略生命周期的函数
    let s = String::from("hello world");
    let word = first_word(&s);
    println!("n第一个单词: {}", word);
    // 结构体中的多个生命周期
    let s1 = String::from("part1");
    let s2 = String::from("part2");
    let multi = MultiLifetime {
    part1: &s1,
    part2: &s2,
    };
    println!("n多个生命周期: part1={}, part2={}", multi.part1, multi.part2);
    // 生命周期总结
    println!("n=== 生命周期总结 ===");
    println!("1. 生命周期确保引用总是有效的");
    println!("2. 使用'<'和'>'定义生命周期参数");
    println!("3. 有三条生命周期省略规则");
    println!("4. 结构体可以包含引用,需要指定生命周期");
    println!("5. 'static生命周期表示整个程序期间都有效");
    println!("6. 可以有多个生命周期参数");
    println!("7. 生命周期可以与泛型和Trait结合使用");
    println!("8. 闭包会自动捕获环境的生命周期");
    }
    use std::fmt;
    use std::fs::File;
    use std::io::{self, BufRead, Write};
    use std::collections::HashMap;
    // 定义Trait
    trait Printable {
    fn print(&self) -> String;
    }
    // 定义枚举
    enum LogLevel {
    Info,
    Warning,
    Error,
    }
    impl fmt::Display for LogLevel {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    match self {
    LogLevel::Info => write!(f, "INFO"),
    LogLevel::Warning => write!(f, "WARNING"),
    LogLevel::Error => write!(f, "ERROR"),
    }
    }
    }
    // 定义结构体
    struct Logger {
    name: String,
    level: LogLevel,
    messages: Vec<String>,
    }
    impl Logger {
    // 关联函数
    fn new(name: &str, level: LogLevel) -> Self {
    Logger {
    name: name.to_string(),
    level,
    messages: Vec::new(),
    }
    }
    // 方法
    fn log(&mut self, level: LogLevel, message: &str) {
    let log_message = format!(
    "[{}] [{}] {}",
    self.name, level, message
    );
    self.messages.push(log_message.clone());
    println!("{}", log_message);
    }
    // 泛型方法
    fn log_formatted<T: fmt::Display>(&mut self, level: LogLevel, message: T) {
    self.log(level, &message.to_string());
    }
    // 保存日志到文件
    fn save_to_file(&self, filename: &str) -> io::Result<()> {
    let mut file = File::create(filename)?;
    for message in &self.messages {
    writeln!(file, "{}", message)?;
    }
    Ok(())
    }
    }
    // 为Logger实现Printable Trait
    impl Printable for Logger {
    fn print(&self) -> String {
    format!(
    "Logger: {}, Level: {}, Messages: {}",
    self.name, self.level, self.messages.len()
    )
    }
    }
    // 错误处理函数
    fn process_file(filename: &str) -> Result<Vec<String>, io::Error> {
    let file = File::open(filename)?;
    let reader = io::BufReader::new(file);
    let mut lines = Vec::new();
    for line in reader.lines() {
    lines.push(line?);
    }
    Ok(lines)
    }
    // 泛型函数
    fn find_max<T: PartialOrd + Copy>(list: &[T]) -> Option<T> {
    if list.is_empty() {
    return None;
    }
    let mut max = list[0];
    for &item in list.iter() {
    if item > max {
    max = item;
    }
    }
    Some(max)
    }
    // 生命周期函数
    fn longest_with_prefix<'a>(s1: &'a str, s2: &'a str, prefix: &str) -> &'a str {
    if s1.starts_with(prefix) && s1.len() > s2.len() {
    s1
    } else if s2.starts_with(prefix) {
    s2
    } else {
    if s1.len() > s2.len() {
    s1
    } else {
    s2
    }
    }
    }
    // 主函数
    fn main() -> io::Result<()> {
    println!("=== Rust综合示例 ===n");
    // 1. 枚举和结构体使用
    let mut logger = Logger::new("app_logger", LogLevel::Info);
    logger.log(LogLevel::Info, "应用程序启动");
    logger.log(LogLevel::Warning, "内存使用过高");
    logger.log(LogLevel::Error, "数据库连接失败");
    // 2. 泛型方法
    logger.log_formatted(LogLevel::Info, 42);
    logger.log_formatted(LogLevel::Info, 3.14159);
    // 3. Trait实现
    println!("n{}", logger.print());
    // 4. 错误处理
    match process_file("log.txt") {
    Ok(lines) => println!("读取到 {} 行日志", lines.len()),
    Err(e) => println!("读取文件失败: {}", e),
    }
    // 5. 泛型函数
    let numbers = vec![1, 3, 5, 2, 4];
    if let Some(max) = find_max(&numbers) {
    println!("n最大值: {}", max);
    }
    let floats = vec![1.1, 2.2, 0.5, 3.3];
    if let Some(max) = find_max(&floats) {
    println!("浮点数最大值: {}", max);
    }
    // 6. 生命周期
    let s1 = String::from("hello world");
    let s2 = String::from("hello rust");
    let longest = longest_with_prefix(&s1, &s2, "hello");
    println!("n最长字符串: {}", longest);
    // 7. 集合操作
    let mut map = HashMap::new();
    map.insert("info", 1);
    map.insert("warning", 1);
    map.insert("error", 1);
    println!("n日志统计:");
    for (level, count) in map {
    println!("{}: {}", level, count);
    }
    // 8. 保存日志到文件
    logger.save_to_file("application.log")?;
    println!("n日志已保存到文件");
    Ok(())
    }
    上一篇
    【香橙派5Plus】 香橙派5plus基础配置
    下一篇
    【Rust环境】如何在Windows的WSL子系统优雅的开发Rust

    评论
    Loading...