第2章 第一个Rust程序

文章目录

  • [第2章 第一个Rust程序](#第2章 第一个Rust程序)
    • [2.1 Hello World程序详解](#2.1 Hello World程序详解)
      • [2.1.1 传统的Hello World程序](#2.1.1 传统的Hello World程序)
      • [2.1.2 深入理解println!宏](#2.1.2 深入理解println!宏)
      • [2.1.3 编译和运行过程详解](#2.1.3 编译和运行过程详解)
      • [2.1.4 理解Rust的编译错误](#2.1.4 理解Rust的编译错误)
    • [2.2 Cargo包管理器入门](#2.2 Cargo包管理器入门)
      • [2.2.1 Cargo项目结构详解](#2.2.1 Cargo项目结构详解)
      • [2.2.2 深入Cargo.toml配置](#2.2.2 深入Cargo.toml配置)
      • [2.2.3 Cargo命令大全](#2.2.3 Cargo命令大全)
      • [2.2.4 创建多二进制项目](#2.2.4 创建多二进制项目)
      • [2.2.5 构建脚本和自定义构建](#2.2.5 构建脚本和自定义构建)
    • [2.3 代码组织结构](#2.3 代码组织结构)
      • [2.3.1 模块系统深度解析](#2.3.1 模块系统深度解析)
      • [2.3.2 可见性和访问控制](#2.3.2 可见性和访问控制)
    • [2.4 基础调试技巧](#2.4 基础调试技巧)
      • [2.4.1 打印调试技术](#2.4.1 打印调试技术)
      • [2.4.2 断言和调试断言](#2.4.2 断言和调试断言)
      • [2.4.3 日志系统集成](#2.4.3 日志系统集成)
      • [2.4.4 调试器集成](#2.4.4 调试器集成)
      • [2.4.5 性能调试和分析](#2.4.5 性能调试和分析)
      • [2.4.6 错误处理和调试](#2.4.6 错误处理和调试)

第2章 第一个Rust程序


2.1 Hello World程序详解

2.1.1 传统的Hello World程序

让我们从最基础的Rust程序开始,深入了解每个组成部分:

rust 复制代码
// 这是main函数 - 程序的入口点
fn main() {
    // 这是一个宏调用,用于向标准输出打印文本
    println!("Hello, World!");
    
    // 让我们添加一些额外的打印来理解程序流程
    println!("程序开始执行...");
    print_message();
    println!("程序执行完毕!");
}

// 定义一个辅助函数
fn print_message() {
    println!("这是从函数中打印的消息!");
    println!("Rust程序的基本结构:");
    println!("1. 使用fn关键字定义函数");
    println!("2. main函数是程序入口");
    println!("3. 语句以分号结尾");
    println!("4. 使用println!宏进行输出");
}

代码分析详解:

  1. 注释系统

    • 单行注释:// 注释内容
    • 文档注释:/// 文档注释(用于生成文档)
  2. 函数定义

    • fn关键字用于声明函数
    • main函数是特殊的入口函数,没有参数和返回值
    • 函数体由大括号{}包围
  3. 宏调用

    • println!是一个宏(注意!符号)
    • 宏在编译时展开,提供强大的元编程能力
    • 字符串字面量用双引号包围

2.1.2 深入理解println!宏

println!宏远比表面看起来强大,让我们探索其各种用法:

rust 复制代码
fn detailed_print_examples() {
    // 基础字符串打印
    println!("简单的字符串打印");
    
    // 位置参数
    println!("{0},这是{1}。{1}很有趣!", "你好", "Rust");
    
    // 命名参数
    println!("{name}今年{age}岁", name = "小明", age = 25);
    
    // 格式化数字
    let pi = 3.1415926;
    println!("π的值是: {:.2}", pi); // 保留两位小数
    println!("二进制: {:b}, 十六进制: {:x}", 255, 255);
    
    // 对齐和填充
    println!("左对齐: {:<10}", "文本");
    println!("右对齐: {:>10}", "文本");
    println!("居中对齐: {:^10}", "文本");
    println!("带填充: {:*^10}", "文本");
    
    // 调试打印
    let complex_data = vec!["apple", "banana", "cherry"];
    println!("调试视图: {:?}", complex_data);
    println!("美化调试: {:#?}", complex_data);
    
    // 表达式求值
    println!("计算结果是: {}", 5 * 3 + 2);
    
    // 多行字符串
    println!("
        这是一个
        多行
        字符串
    ");
}

2.1.3 编译和运行过程详解

让我们深入了解Rust程序的编译和执行过程:

rust 复制代码
// 预处理指令(属性)
#![allow(unused_variables)] // 允许未使用的变量警告

/// 这个函数演示了Rust的编译时检查
fn compile_time_checks() {
    // 类型检查
    let x: i32 = 42; // 明确的类型注解
    let y = 3.14;    // 类型推断
    
    // 所有权检查
    let s1 = String::from("hello");
    let s2 = s1; // 所有权转移
    // println!("{}", s1); // 这行会编译错误!
    
    // 借用检查
    let mut data = vec![1, 2, 3];
    let reference = &data[0]; // 不可变借用
    // data.push(4); // 这行会编译错误!不能同时存在可变和不可变借用
    println!("引用: {}", reference);
}

fn main() {
    println!("=== Rust程序执行流程 ===");
    
    // 1. 程序启动
    println!("1. 程序启动,main函数被调用");
    
    // 2. 栈内存分配
    let stack_variable = 100;
    println!("2. 栈变量创建: {}", stack_variable);
    
    // 3. 堆内存分配
    let heap_variable = String::from("堆上的字符串");
    println!("3. 堆变量创建: {}", heap_variable);
    
    // 4. 函数调用
    nested_function();
    
    // 5. 作用域结束,资源清理
    println!("5. main函数即将结束,自动清理资源");
}

fn nested_function() {
    println!("4. 进入嵌套函数");
    let local_var = "局部变量";
    println!("   在函数内创建: {}", local_var);
    println!("   函数结束,局部变量被清理");
}

2.1.4 理解Rust的编译错误

Rust编译器以提供有用的错误信息而闻名。让我们故意制造一些错误来理解编译器的工作方式:

rust 复制代码
fn understanding_compiler_errors() {
    // 取消下面的注释来查看各种编译错误
    
    // 错误1: 类型不匹配
    // let x: i32 = "hello"; // 期望i32,找到&str
    
    // 错误2: 使用未初始化的变量
    // let y: i32;
    // println!("{}", y); // 使用了可能未初始化的变量
    
    // 错误3: 所有权错误
    // let s1 = String::from("text");
    // let s2 = s1;
    // println!("{}", s1); // s1的所有权已移动
    
    // 错误4: 借用规则违反
    // let mut v = vec![1, 2, 3];
    // let first = &v[0];
    // v.push(4); // 不能可变借用,因为已有不可变借用
    
    println!("如果上面的注释被取消,编译将会失败");
}

2.2 Cargo包管理器入门

2.2.1 Cargo项目结构详解

让我们深入了解Cargo创建的完整项目结构:

bash 复制代码
# 创建新项目
cargo new comprehensive_hello --bin
cd comprehensive_hello

项目结构分析:

复制代码
comprehensive_hello/
├── Cargo.toml              # 项目配置和依赖管理
├── Cargo.lock              # 精确的依赖版本锁定(自动生成)
├── .gitignore              # Git忽略文件配置
├── .cargo/                 # Cargo配置目录
│   └── config.toml         # 本地Cargo配置
└── src/
    ├── main.rs             # 主程序入口
    ├── lib.rs              # 库代码(如果存在)
    ├── bin/                # 额外的二进制目标
    │   ├── helper1.rs
    │   └── helper2.rs
    └── utils/              # 工具模块
        ├── mod.rs
        └── math.rs

2.2.2 深入Cargo.toml配置

让我们创建一个功能完整的Cargo.toml文件:

toml 复制代码
[package]
name = "comprehensive_hello"
version = "0.1.0"
authors = ["你的名字 <email@example.com>"]
edition = "2021"
description = "一个全面的Rust Hello World示例"
license = "MIT OR Apache-2.0"
readme = "README.md"
homepage = "https://github.com/username/comprehensive_hello"
repository = "https://github.com/username/comprehensive_hello"
keywords = ["hello", "example", "learning"]
categories = ["command-line-utilities"]

# 参见更多键及其定义:https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
# 标准库依赖(隐式包含)
# 外部crate依赖
chrono = { version = "0.4", features = ["serde"] }
rand = "0.8.5"
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }

[dev-dependencies]
# 开发时依赖(测试、示例、基准测试)
assert_cmd = "2.0"
tempfile = "3.3"

[build-dependencies]
# 构建脚本依赖
cc = "1.0"

[features]
# 条件编译特性
default = ["logging", "network"]
logging = ["dep:log", "dep:env_logger"]  # 显式特性依赖
network = ["dep:reqwest"]
advanced = []

[[bin]]
name = "comprehensive_hello"
path = "src/main.rs"

[[bin]]
name = "helper_tool"
path = "src/bin/helper1.rs"

[profile.dev]
opt-level = 0
debug = true
debug-assertions = true
overflow-checks = true
lto = false
panic = 'unwind'
incremental = true
codegen-units = 256
rpath = false

[profile.release]
opt-level = 3
debug = false
debug-assertions = false
overflow-checks = false
lto = true
panic = 'abort'
incremental = false
codegen-units = 1
rpath = false

[workspace]
# 工作区配置(对于更大的项目)
# members = ["crates/*"]

2.2.3 Cargo命令大全

让我们探索Cargo的各种命令和用法:

rust 复制代码
// src/main.rs - 主程序文件
use std::process::Command;

fn main() {
    println!("=== Cargo 命令演示 ===");
    
    // 模拟各种Cargo命令的使用场景
    demonstrate_cargo_commands();
    
    // 构建配置示例
    build_configuration_example();
}

fn demonstrate_cargo_commands() {
    println!("\n1. 基础构建命令:");
    println!("   cargo build          - 开发构建");
    println!("   cargo build --release - 发布构建");
    println!("   cargo check          - 快速编译检查");
    println!("   cargo run            - 编译并运行");
    println!("   cargo clean          - 清理构建产物");
    
    println!("\n2. 依赖管理命令:");
    println!("   cargo add <crate>    - 添加依赖");
    println!("   cargo update         - 更新依赖");
    println!("   cargo tree           - 显示依赖树");
    println!("   cargo search <term>  - 搜索crate");
    
    println!("\n3. 测试和检查命令:");
    println!("   cargo test           - 运行测试");
    println!("   cargo bench          - 运行基准测试");
    println!("   cargo doc            - 生成文档");
    println!("   cargo doc --open     - 生成并打开文档");
    println!("   cargo fmt            - 代码格式化");
    println!("   cargo clippy         - 代码检查");
    
    println!("\n4. 发布和分发命令:");
    println!("   cargo publish        - 发布到crates.io");
    println!("   cargo install <crate> - 安装二进制crate");
    println!("   cargo uninstall <crate> - 卸载二进制crate");
}

fn build_configuration_example() {
    println!("\n=== 构建配置示例 ===");
    
    // 条件编译示例
    #[cfg(debug_assertions)]
    println!("当前是调试构建");
    
    #[cfg(not(debug_assertions))]
    println!("当前是发布构建");
    
    // 特性标志示例
    #[cfg(feature = "logging")]
    println!("日志特性已启用");
    
    #[cfg(feature = "network")]
    println!("网络特性已启用");
    
    // 平台特定代码
    #[cfg(target_os = "linux")]
    println!("运行在Linux系统上");
    
    #[cfg(target_os = "windows")]
    println!("运行在Windows系统上");
    
    #[cfg(target_os = "macos")]
    println!("运行在macOS系统上");
}

2.2.4 创建多二进制项目

让我们创建一个包含多个二进制目标的复杂项目:

src/bin/helper1.rs:

rust 复制代码
//! 辅助工具1 - 数学计算器

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    
    if args.len() != 4 {
        eprintln!("用法: {} <操作> <数字1> <数字2>", args[0]);
        eprintln!("操作: add, sub, mul, div");
        std::process::exit(1);
    }
    
    let operation = &args[1];
    let num1: f64 = args[2].parse().expect("无效的数字");
    let num2: f64 = args[3].parse().expect("无效的数字");
    
    let result = match operation.as_str() {
        "add" => num1 + num2,
        "sub" => num1 - num2,
        "mul" => num1 * num2,
        "div" => {
            if num2 == 0.0 {
                eprintln!("错误: 除数不能为零");
                std::process::exit(1);
            }
            num1 / num2
        }
        _ => {
            eprintln!("错误: 未知操作 '{}'", operation);
            std::process::exit(1);
        }
    };
    
    println!("结果: {} {} {} = {}", num1, operation, num2, result);
}

src/bin/helper2.rs:

rust 复制代码
//! 辅助工具2 - 文件信息查看器

use std::env;
use std::fs;
use std::path::Path;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args: Vec<String> = env::args().collect();
    
    if args.len() != 2 {
        eprintln!("用法: {} <文件路径>", args[0]);
        std::process::exit(1);
    }
    
    let path = Path::new(&args[1]);
    
    if !path.exists() {
        eprintln!("错误: 文件不存在 '{}'", path.display());
        std::process::exit(1);
    }
    
    let metadata = fs::metadata(path)?;
    
    println!("文件信息:");
    println!("  路径: {}", path.display());
    println!("  大小: {} 字节", metadata.len());
    println!("  是否文件: {}", metadata.is_file());
    println!("  是否目录: {}", metadata.is_dir());
    
    if let Ok(modified) = metadata.modified() {
        println!("  修改时间: {:?}", modified);
    }
    
    if let Ok(permissions) = metadata.permissions() {
        println!("  权限: {:?}", permissions);
    }
    
    Ok(())
}

2.2.5 构建脚本和自定义构建

build.rs - 自定义构建脚本:

rust 复制代码
use std::env;
use std::fs;
use std::path::Path;
use std::process::Command;

fn main() {
    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed=src/");
    
    // 设置环境变量
    let package_name = env::var("CARGO_PKG_NAME").unwrap();
    let package_version = env::var("CARGO_PKG_VERSION").unwrap();
    
    println!("cargo:warning=构建 {} 版本 {}", package_name, package_version);
    
    // 生成版本信息文件
    let out_dir = env::var("OUT_DIR").unwrap();
    let version_file = Path::new(&out_dir).join("version_info.rs");
    
    let version_info = format!(
        r#"
        pub const PACKAGE_NAME: &str = "{}";
        pub const PACKAGE_VERSION: &str = "{}";
        pub const BUILD_TIME: &str = "{}";
        "#,
        package_name,
        package_version,
        chrono::Utc::now().to_rfc3339()
    );
    
    fs::write(&version_file, version_info).unwrap();
    println!("cargo:rustc-env=VERSION_INFO_RS={}", version_file.display());
    
    // 条件编译设置
    if cfg!(target_os = "linux") {
        println!("cargo:rustc-cfg=unix");
    }
    
    // 链接系统库示例
    if cfg!(target_os = "linux") {
        println!("cargo:rustc-link-lib=dylib=dl");
    }
}

2.3 代码组织结构

2.3.1 模块系统深度解析

Rust的模块系统是其代码组织的核心。让我们创建一个复杂的模块结构:

src/main.rs:

rust 复制代码
// 声明外部模块
mod utils;
mod math_operations;
mod network;

// 使用use关键字导入
use utils::file_utils;
use math_operations::{basic_math, advanced_math};
use network::http_client;

// 重导出
pub use utils::Config;

fn main() {
    println!("=== 模块系统演示 ===");
    
    // 使用模块中的功能
    file_utils::read_file_simulation("config.txt");
    
    let sum = basic_math::add(10, 20);
    println!("10 + 20 = {}", sum);
    
    let factorial = advanced_math::factorial(5);
    println!("5! = {}", factorial);
    
    http_client::make_request_simulation("https://api.example.com/data");
    
    // 使用重导出的类型
    let config = Config::new("app.conf");
    config.display();
}

src/utils/mod.rs:

rust 复制代码
//! 工具模块
//! 
//! 这个模块包含各种实用工具函数和类型。

// 子模块
pub mod file_utils;
pub mod string_utils;

// 公开的结构体
pub struct Config {
    pub filename: String,
    pub debug_mode: bool,
}

impl Config {
    pub fn new(filename: &str) -> Self {
        Self {
            filename: filename.to_string(),
            debug_mode: cfg!(debug_assertions),
        }
    }
    
    pub fn display(&self) {
        println!("配置文件: {}", self.filename);
        println!("调试模式: {}", self.debug_mode);
    }
}

// 模块级别的文档测试
#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_config_creation() {
        let config = Config::new("test.conf");
        assert_eq!(config.filename, "test.conf");
    }
}

src/utils/file_utils.rs:

rust 复制代码
//! 文件操作工具函数

use std::path::Path;
use std::fs;
use std::io;

/// 模拟读取文件内容
/// 
/// # 参数
/// 
/// * `filename` - 要读取的文件名
/// 
/// # 示例
/// 
/// ```
/// use comprehensive_hello::utils::file_utils;
/// file_utils::read_file_simulation("config.txt");
/// ```
pub fn read_file_simulation(filename: &str) -> String {
    println!("读取文件: {}", filename);
    
    // 在实际应用中,这里会有真正的文件读取逻辑
    if Path::new(filename).exists() {
        format!("文件 {} 的内容", filename)
    } else {
        String::from("文件不存在")
    }
}

/// 安全的文件读取函数
pub fn read_file_safe(filename: &str) -> Result<String, io::Error> {
    fs::read_to_string(filename)
}

/// 文件信息结构体
pub struct FileInfo {
    pub size: u64,
    pub is_readable: bool,
    pub is_writable: bool,
}

impl FileInfo {
    pub fn new(filename: &str) -> Self {
        let metadata = fs::metadata(filename).unwrap_or_else(|_| {
            panic!("无法获取文件元数据: {}", filename)
        });
        
        Self {
            size: metadata.len(),
            is_readable: true, // 简化实现
            is_writable: true, // 简化实现
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use tempfile::NamedTempFile;
    
    #[test]
    fn test_file_info() {
        let temp_file = NamedTempFile::new().unwrap();
        let file_info = FileInfo::new(temp_file.path().to_str().unwrap());
        
        assert!(file_info.size >= 0);
        assert!(file_info.is_readable);
    }
}

src/utils/string_utils.rs:

rust 复制代码
//! 字符串处理工具

/// 反转字符串
pub fn reverse_string(s: &str) -> String {
    s.chars().rev().collect()
}

/// 检查字符串是否为回文
pub fn is_palindrome(s: &str) -> bool {
    let cleaned: String = s.chars()
        .filter(|c| c.is_alphanumeric())
        .collect::<String>()
        .to_lowercase();
    
    cleaned == reverse_string(&cleaned)
}

/// 统计单词数量
pub fn count_words(text: &str) -> usize {
    text.split_whitespace().count()
}

/// 字符串转换 trait
pub trait StringConversion {
    fn to_camel_case(&self) -> String;
    fn to_snake_case(&self) -> String;
}

impl StringConversion for str {
    fn to_camel_case(&self) -> String {
        let mut result = String::new();
        let mut capitalize_next = false;
        
        for c in self.chars() {
            if c == '_' {
                capitalize_next = true;
            } else if capitalize_next {
                result.push(c.to_ascii_uppercase());
                capitalize_next = false;
            } else {
                result.push(c);
            }
        }
        result
    }
    
    fn to_snake_case(&self) -> String {
        let mut result = String::new();
        
        for (i, c) in self.chars().enumerate() {
            if c.is_ascii_uppercase() && i > 0 {
                result.push('_');
            }
            result.push(c.to_ascii_lowercase());
        }
        result
    }
}

src/math_operations/mod.rs:

rust 复制代码
//! 数学运算模块

pub mod basic_math;
pub mod advanced_math;

// 重导出常用功能
pub use basic_math::{add, subtract, multiply, divide};
pub use advanced_math::{factorial, fibonacci, is_prime};

src/math_operations/basic_math.rs:

rust 复制代码
//! 基础数学运算

/// 加法运算
/// 
/// # 示例
/// 
/// ```
/// use comprehensive_hello::math_operations::basic_math::add;
/// assert_eq!(add(2, 3), 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

/// 减法运算
pub fn subtract(a: i32, b: i32) -> i32 {
    a - b
}

/// 乘法运算
pub fn multiply(a: i32, b: i32) -> i32 {
    a * b
}

/// 除法运算
/// 
/// # 错误
/// 
/// 如果除数为零,会panic
pub fn divide(a: i32, b: i32) -> i32 {
    if b == 0 {
        panic!("除数不能为零");
    }
    a / b
}

/// 安全的除法运算
pub fn divide_safe(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err("除数不能为零".to_string())
    } else {
        Ok(a / b)
    }
}

src/math_operations/advanced_math.rs:

rust 复制代码
//! 高级数学运算

/// 计算阶乘
/// 
/// # 参数
/// 
/// * `n` - 要计算阶乘的非负整数
/// 
/// # 返回值
/// 
/// n的阶乘,如果n=0则返回1
pub fn factorial(n: u64) -> u64 {
    match n {
        0 | 1 => 1,
        _ => n * factorial(n - 1),
    }
}

/// 计算斐波那契数列的第n项
pub fn fibonacci(n: u32) -> u64 {
    if n == 0 {
        return 0;
    }
    if n == 1 {
        return 1;
    }
    
    let mut a = 0;
    let mut b = 1;
    
    for _ in 2..=n {
        let temp = a + b;
        a = b;
        b = temp;
    }
    
    b
}

/// 检查数字是否为质数
pub fn is_prime(n: u64) -> bool {
    if n <= 1 {
        return false;
    }
    if n <= 3 {
        return true;
    }
    if n % 2 == 0 || n % 3 == 0 {
        return false;
    }
    
    let mut i = 5;
    while i * i <= n {
        if n % i == 0 || n % (i + 2) == 0 {
            return false;
        }
        i += 6;
    }
    
    true
}

/// 最大公约数
pub fn gcd(mut a: u64, mut b: u64) -> u64 {
    while b != 0 {
        let temp = b;
        b = a % b;
        a = temp;
    }
    a
}

/// 最小公倍数
pub fn lcm(a: u64, b: u64) -> u64 {
    if a == 0 || b == 0 {
        0
    } else {
        (a * b) / gcd(a, b)
    }
}

src/network/mod.rs:

rust 复制代码
//! 网络相关功能

pub mod http_client;
pub mod tcp_server;

// 网络错误类型
#[derive(Debug)]
pub enum NetworkError {
    ConnectionFailed,
    Timeout,
    InvalidResponse,
    IoError(std::io::Error),
}

impl From<std::io::Error> for NetworkError {
    fn from(error: std::io::Error) -> Self {
        NetworkError::IoError(error)
    }
}

src/network/http_client.rs:

rust 复制代码
//! HTTP客户端模拟

use super::NetworkError;

/// HTTP请求方法
#[derive(Debug, Clone)]
pub enum HttpMethod {
    GET,
    POST,
    PUT,
    DELETE,
}

/// HTTP请求结构体
pub struct HttpRequest {
    pub method: HttpMethod,
    pub url: String,
    pub headers: Vec<(String, String)>,
    pub body: Option<String>,
}

impl HttpRequest {
    pub fn new(method: HttpMethod, url: &str) -> Self {
        Self {
            method,
            url: url.to_string(),
            headers: Vec::new(),
            body: None,
        }
    }
    
    pub fn add_header(mut self, key: &str, value: &str) -> Self {
        self.headers.push((key.to_string(), value.to_string()));
        self
    }
    
    pub fn set_body(mut self, body: &str) -> Self {
        self.body = Some(body.to_string());
        self
    }
}

/// 模拟HTTP请求
pub fn make_request_simulation(url: &str) -> Result<String, NetworkError> {
    println!("模拟HTTP请求到: {}", url);
    
    // 在实际应用中,这里会有真正的HTTP请求逻辑
    if url.starts_with("https://") {
        Ok(format!("响应来自 {}", url))
    } else {
        Err(NetworkError::ConnectionFailed)
    }
}

/// 异步HTTP请求(需要启用async特性)
#[cfg(feature = "network")]
pub async fn make_async_request(url: &str) -> Result<String, NetworkError> {
    // 在实际应用中,这里会使用真正的异步HTTP客户端
    tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
    make_request_simulation(url)
}

2.3.2 可见性和访问控制

理解Rust的可见性规则:

rust 复制代码
// src/visibility_demo.rs
mod visibility_demo {
    // 公开的结构体,但字段默认私有
    pub struct PublicStruct {
        public_field: String,    // 私有字段
        pub public_field2: String, // 公开字段
    }
    
    impl PublicStruct {
        // 公开的构造函数
        pub fn new(value: &str) -> Self {
            Self {
                public_field: value.to_string(),
                public_field2: value.to_string(),
            }
        }
        
        // 公开的方法可以访问私有字段
        pub fn get_private_field(&self) -> &str {
            &self.public_field
        }
        
        // 私有方法
        fn private_method(&self) {
            println!("这是私有方法");
        }
    }
    
    // 私有结构体,只在模块内可见
    struct PrivateStruct {
        field: i32,
    }
    
    // 模块内的公共接口
    pub fn public_function() {
        println!("这是公开函数");
        private_function(); // 可以调用私有函数
    }
    
    // 私有函数,只在模块内可见
    fn private_function() {
        println!("这是私有函数");
    }
    
    // 嵌套模块的可见性
    pub mod nested {
        pub fn function() {
            println!("嵌套模块的公开函数");
            super::private_function(); // 可以访问父模块的私有项
        }
        
        // 只在父模块内可见
        pub(crate) fn crate_visible() {
            println!("只在crate内可见");
        }
        
        // 只在特定路径可见
        pub(in crate::visibility_demo) fn module_visible() {
            println!("只在visibility_demo模块内可见");
        }
    }
}

fn test_visibility() {
    use visibility_demo::PublicStruct;
    
    let instance = PublicStruct::new("test");
    println!("{}", instance.public_field2); // OK
    // println!("{}", instance.public_field); // 错误:字段私有
    println!("{}", instance.get_private_field()); // OK
    
    visibility_demo::public_function(); // OK
    // visibility_demo::private_function(); // 错误:函数私有
    
    visibility_demo::nested::function(); // OK
}

2.4 基础调试技巧

2.4.1 打印调试技术

Rust提供了多种打印调试的方法:

rust 复制代码
// src/debugging.rs
#[derive(Debug)] // 自动实现Debug trait
struct User {
    name: String,
    age: u32,
    email: String,
}

fn print_debugging_techniques() {
    println!("=== 打印调试技术 ===");
    
    let user = User {
        name: "张三".to_string(),
        age: 25,
        email: "zhangsan@example.com".to_string(),
    };
    
    // 1. 基础println!
    println!("用户: {}", user.name);
    
    // 2. 调试打印
    println!("用户详情: {:?}", user);
    println!("美化调试: {:#?}", user);
    
    // 3. dbg!宏 - 非常强大的调试工具
    let x = 5;
    let y = 10;
    let sum = dbg!(x * y + 15);
    dbg!(&user);
    
    // 4. 格式化的调试输出
    println!("调试信息: name={}, age={}, email={}", 
             user.name, user.age, user.email);
    
    // 5. 使用eprintln!打印到标准错误
    eprintln!("警告: 这是错误输出");
    
    // 6. 条件调试打印
    if cfg!(debug_assertions) {
        println!("这是调试构建的额外信息");
    }
}

fn advanced_dbg_usage() {
    println!("\n=== 高级dbg!用法 ===");
    
    // dbg!在表达式中的使用
    let numbers = vec![1, 2, 3, 4, 5];
    
    let result: Vec<i32> = numbers
        .iter()
        .map(|x| dbg!(x * 2))
        .filter(|x| dbg!(x > &4))
        .collect();
    
    dbg!(result);
    
    // 函数调用调试
    fn factorial(n: u32) -> u32 {
        if n <= 1 {
            dbg!(1)
        } else {
            dbg!(n * factorial(n - 1))
        }
    }
    
    dbg!(factorial(4));
}

2.4.2 断言和调试断言

rust 复制代码
fn assertion_techniques() {
    println!("=== 断言技术 ===");
    
    let value = 42;
    
    // 基础断言
    assert!(value > 0);
    assert_eq!(value, 42);
    assert_ne!(value, 0);
    
    // 带消息的断言
    assert!(value < 100, "值应该小于100,但得到 {}", value);
    
    // 调试断言(只在调试构建中检查)
    debug_assert!(value > 0, "调试断言失败");
    
    // 不可达代码断言
    let status = "success";
    match status {
        "success" => println!("操作成功"),
        "error" => println!("操作失败"),
        _ => unreachable!("未知状态"),
    }
    
    // 实现自定义断言函数
    fn assert_valid_age(age: u32) {
        assert!(age <= 150, "无效的年龄: {}", age);
        assert!(age > 0, "年龄必须为正数");
    }
    
    assert_valid_age(25);
    // assert_valid_age(200); // 这会panic
}

fn panic_handling() {
    println!("\n=== Panic处理 ===");
    
    // 1. 基本的panic
    // panic!("这是一个panic!");
    
    // 2. 条件panic
    let should_panic = false;
    if should_panic {
        panic!("条件触发的panic");
    }
    
    // 3. 未实现的功能
    fn not_implemented() -> ! {
        unimplemented!("这个功能还没有实现");
    }
    
    // 4. 未支持的功能
    fn unsupported_operation() -> ! {
        unreachable!("这个操作不应该被调用");
    }
    
    // 5. 可选值的解包
    let maybe_value: Option<i32> = Some(42);
    let value = maybe_value.expect("值不应该为None");
    println!("解包的值: {}", value);
    
    // 6. 结果的解包
    let result: Result<i32, &str> = Ok(100);
    let value = result.expect("操作不应该失败");
    println!("结果值: {}", value);
}

2.4.3 日志系统集成

让我们集成一个完整的日志系统:

Cargo.toml添加依赖:

toml 复制代码
[dependencies]
log = "0.4"
env_logger = "0.10"

[features]
default = ["logging"]
logging = ["dep:log", "dep:env_logger"]

src/logging_demo.rs:

rust 复制代码
#[cfg(feature = "logging")]
use log::{debug, info, warn, error, trace};

#[cfg(feature = "logging")]
pub fn setup_logging() {
    use env_logger::Env;
    
    env_logger::Builder::from_env(Env::default().default_filter_or("info"))
        .format_timestamp_millis()
        .format_module_path(false)
        .init();
    
    info!("日志系统初始化完成");
}

#[cfg(feature = "logging")]
pub fn demonstrate_logging() {
    trace!("这是最详细的跟踪信息");
    debug!("调试信息 - 变量值: {}", 42);
    info!("普通信息 - 应用程序正常执行");
    warn!("警告信息 - 需要注意的情况");
    error!("错误信息 - 严重问题发生");
    
    // 结构化日志
    info!(
        user_id = 12345,
        action = "login",
        "用户执行操作"
    );
}

#[cfg(not(feature = "logging"))]
pub fn setup_logging() {
    println!("日志特性未启用");
}

#[cfg(not(feature = "logging"))]
pub fn demonstrate_logging() {
    println!("日志特性未启用,使用println代替");
    println!("[INFO] 模拟日志信息");
}

2.4.4 调试器集成

配置VS Code进行高级调试:

.vscode/launch.json:

json 复制代码
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "launch",
            "name": "Debug Main",
            "program": "${workspaceFolder}/target/debug/comprehensive_hello",
            "args": [],
            "cwd": "${workspaceFolder}",
            "preLaunchTask": "cargo build"
        },
        {
            "type": "lldb",
            "request": "launch",
            "name": "Debug Tests",
            "program": "${workspaceFolder}/target/debug/comprehensive_hello",
            "args": ["--test-threads=1"],
            "cwd": "${workspaceFolder}",
            "preLaunchTask": "cargo test --no-run"
        },
        {
            "type": "lldb",
            "request": "launch",
            "name": "Debug Helper Tool",
            "program": "${workspaceFolder}/target/debug/helper_tool",
            "args": ["add", "10", "20"],
            "cwd": "${workspaceFolder}",
            "preLaunchTask": "cargo build --bin helper_tool"
        }
    ]
}

.vscode/tasks.json:

json 复制代码
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "cargo build",
            "type": "shell",
            "command": "cargo",
            "args": ["build"],
            "group": "build",
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared"
            },
            "problemMatcher": [
                "$rustc"
            ]
        },
        {
            "label": "cargo test",
            "type": "shell",
            "command": "cargo",
            "args": ["test", "--no-run"],
            "group": "build",
            "presentation": {
                "echo": true,
                "reveal": "always",
                "focus": false,
                "panel": "shared"
            },
            "problemMatcher": [
                "$rustc"
            ]
        }
    ]
}

2.4.5 性能调试和分析

rust 复制代码
fn performance_debugging() {
    println!("=== 性能调试 ===");
    
    use std::time::Instant;
    
    // 测量执行时间
    let start = Instant::now();
    
    // 模拟一些工作
    let mut sum = 0;
    for i in 0..1_000_000 {
        sum += i;
    }
    
    let duration = start.elapsed();
    println!("计算耗时: {:?}", duration);
    println!("结果: {}", sum);
    
    // 内存使用分析
    memory_usage_analysis();
}

fn memory_usage_analysis() {
    println!("\n=== 内存使用分析 ===");
    
    use std::mem;
    
    // 检查类型大小
    println!("i32大小: {} 字节", mem::size_of::<i32>());
    println!("String大小: {} 字节", mem::size_of::<String>());
    println!("Vec<i32>大小: {} 字节", mem::size_of::<Vec<i32>>());
    
    // 堆分配分析
    let small_vec: Vec<i32> = vec![1, 2, 3];
    let large_vec: Vec<i32> = (0..1000).collect();
    
    println!("小向量容量: {}, 长度: {}", small_vec.capacity(), small_vec.len());
    println!("大向量容量: {}, 长度: {}", large_vec.capacity(), large_vec.len());
    
    // 内存对齐
    println!("i32对齐: {} 字节", mem::align_of::<i32>());
    println!("String对齐: {} 字节", mem::align_of::<String>());
}

// 基准测试示例
#[cfg(test)]
mod benchmarks {
    use super::*;
    
    #[test]
    fn test_performance() {
        let start = Instant::now();
        
        // 测试代码
        let result = advanced_math::fibonacci(30);
        
        let duration = start.elapsed();
        assert!(duration.as_millis() < 100, "性能测试失败: 执行时间过长");
        assert_eq!(result, 832040);
    }
}

2.4.6 错误处理和调试

rust 复制代码
fn comprehensive_error_handling() {
    println!("=== 综合错误处理 ===");
    
    // 1. 基本的Result处理
    match divide_with_result(10, 0) {
        Ok(result) => println!("除法结果: {}", result),
        Err(e) => println!("错误: {}", e),
    }
    
    // 2. 使用unwrap和expect
    let value = divide_with_result(10, 2).unwrap();
    println!("安全除法结果: {}", value);
    
    // 3. 使用?操作符传播错误
    if let Err(e) = process_division() {
        println!("处理过程中出错: {}", e);
    }
    
    // 4. 自定义错误类型
    match complex_operation() {
        Ok(result) => println!("复杂操作成功: {}", result),
        Err(MyError::DivisionError(msg)) => println!("除法错误: {}", msg),
        Err(MyError::ValidationError(msg)) => println!("验证错误: {}", msg),
        Err(MyError::NetworkError(msg)) => println!("网络错误: {}", msg),
    }
}

fn divide_with_result(a: i32, b: i32) -> Result<i32, String> {
    if b == 0 {
        Err("除数不能为零".to_string())
    } else {
        Ok(a / b)
    }
}

fn process_division() -> Result<(), String> {
    let result1 = divide_with_result(20, 4)?;
    let result2 = divide_with_result(result1, 2)?;
    println!("链式除法结果: {}", result2);
    Ok(())
}

// 自定义错误类型
#[derive(Debug)]
enum MyError {
    DivisionError(String),
    ValidationError(String),
    NetworkError(String),
}

fn complex_operation() -> Result<i32, MyError> {
    // 模拟可能失败的操作
    let input = 10;
    
    if input < 0 {
        return Err(MyError::ValidationError("输入不能为负".to_string()));
    }
    
    let result = divide_with_result(input, 2)
        .map_err(|e| MyError::DivisionError(e))?;
    
    // 模拟网络操作
    if result > 100 {
        return Err(MyError::NetworkError("结果太大".to_string()));
    }
    
    Ok(result)
}

通过本章的全面学习,你已经深入掌握了创建、组织、构建和调试Rust程序的所有基础知识。从简单的Hello World程序到复杂的多模块项目,你现在应该能够自信地开始编写自己的Rust程序了。在下一章中,我们将深入探讨Rust的变量和数据类型系统。

相关推荐
Zhangzy@8 小时前
Rust 中的注释与文档注释实践指南
开发语言·后端·rust
alwaysrun8 小时前
Rust编译参数与优化控制
rust·cargo·rustc·profile·strip·lto
像风一样自由20208 小时前
使用 Rust 开发图片切分工具:从零到发布的完整指南
开发语言·后端·rust
折翼的恶魔8 小时前
SQL190 0级用户高难度试卷的平均用时和平均得分
java·数据库
Mos_x8 小时前
Python爬虫---中国大学MOOC爬取数据(文中有
java·后端
半夏知半秋9 小时前
mongodb的复制集整理
服务器·开发语言·数据库·后端·学习·mongodb
一点七加一9 小时前
Harmony鸿蒙开发0基础入门到精通Day09--JavaScript篇
开发语言·javascript·ecmascript
nvd119 小时前
python异步编程 -协程的实际意义
开发语言·python