Skip to content

Rust 注释

概述

注释是代码中的重要组成部分,用于解释代码逻辑、生成文档、标记待办事项等。Rust 提供了多种注释方式,本章将详细介绍各种注释语法和最佳实践。

💬 基本注释

行注释

rust
fn line_comments() {
    // 这是一个单行注释
    let x = 5; // 行尾注释
    
    // 多行注释可以这样写
    // 每一行都需要双斜杠
    // 这样的注释很清晰
    
    let y = 10;
    
    // TODO: 实现更复杂的逻辑
    // FIXME: 修复这里的性能问题
    // NOTE: 这里需要特别注意
    // HACK: 临时解决方案
    
    println!("x: {}, y: {}", x, y);
}

块注释

rust
fn block_comments() {
    /*
     * 这是一个块注释
     * 可以跨越多行
     * 通常用于大段的注释
     */
    let message = "Hello, World!";
    
    /* 简单的块注释 */
    let number = 42;
    
    /*
    块注释可以嵌套
    /*
        像这样嵌套
        /* 甚至可以多层嵌套 */
    */
    */
    
    println!("{}: {}", message, number);
}

注释中的代码

rust
fn commented_code() {
    let active_code = "这行会执行";
    
    // let commented_code = "这行不会执行";
    
    /*
    let block_commented = "这些代码";
    let all_commented = "都不会执行";
    */
    
    println!("{}", active_code);
}

📚 文档注释

外部文档注释

rust
/// 计算两个数的和
/// 
/// # 参数
/// 
/// * `a` - 第一个数字
/// * `b` - 第二个数字
/// 
/// # 返回值
/// 
/// 返回两个数字的和
/// 
/// # 示例
/// 
/// ```
/// use my_crate::add;
/// 
/// let result = add(2, 3);
/// assert_eq!(result, 5);
/// ```
/// 
/// # 注意
/// 
/// 这个函数可能会溢出
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

/// 表示一个用户的结构体
/// 
/// # 字段
/// 
/// * `id` - 用户的唯一标识符
/// * `name` - 用户的姓名
/// * `email` - 用户的邮箱地址
/// 
/// # 示例
/// 
/// ```
/// use my_crate::User;
/// 
/// let user = User {
///     id: 1,
///     name: String::from("Alice"),
///     email: String::from("alice@example.com"),
/// };
/// 
/// println!("用户: {}", user.name);
/// ```
pub struct User {
    /// 用户ID
    pub id: u32,
    /// 用户姓名
    pub name: String,
    /// 用户邮箱
    pub email: String,
}

impl User {
    /// 创建新用户
    /// 
    /// # 参数
    /// 
    /// * `name` - 用户姓名
    /// * `email` - 用户邮箱
    /// 
    /// # 返回值
    /// 
    /// 返回新创建的用户实例
    /// 
    /// # 示例
    /// 
    /// ```
    /// use my_crate::User;
    /// 
    /// let user = User::new("Bob".to_string(), "bob@example.com".to_string());
    /// assert_eq!(user.name, "Bob");
    /// ```
    pub fn new(name: String, email: String) -> Self {
        Self {
            id: 0, // 简化示例
            name,
            email,
        }
    }
    
    /// 检查用户是否有效
    /// 
    /// # 返回值
    /// 
    /// 如果用户信息有效返回 `true`,否则返回 `false`
    /// 
    /// # 示例
    /// 
    /// ```
    /// use my_crate::User;
    /// 
    /// let user = User::new("Charlie".to_string(), "charlie@example.com".to_string());
    /// assert!(user.is_valid());
    /// ```
    pub fn is_valid(&self) -> bool {
        !self.name.is_empty() && self.email.contains('@')
    }
}

内部文档注释

rust
//! 这是模块级别的文档注释
//! 
//! 这个模块提供了用户管理的功能
//! 
//! # 功能
//! 
//! - 创建用户
//! - 验证用户信息
//! - 用户数据管理
//! 
//! # 使用方法
//! 
//! ```
//! use user_module::User;
//! 
//! let user = User::new("Alice".to_string(), "alice@example.com".to_string());
//! println!("用户: {}", user.name);
//! ```

pub mod user_management {
    /*! 
     * 这也是模块级别的文档注释
     * 使用块注释的方式
     */
    
    //! # 用户管理模块
    //! 
    //! 提供完整的用户管理功能
    
    pub fn create_user(name: &str, email: &str) -> bool {
        // 创建用户的逻辑
        !name.is_empty() && email.contains('@')
    }
}

📖 文档示例和测试

可运行的文档示例

rust
/// 计算阶乘
/// 
/// # 参数
/// 
/// * `n` - 要计算阶乘的数字
/// 
/// # 返回值
/// 
/// 返回 n 的阶乘
/// 
/// # 示例
/// 
/// ```
/// use my_crate::factorial;
/// 
/// assert_eq!(factorial(0), 1);
/// assert_eq!(factorial(1), 1);
/// assert_eq!(factorial(5), 120);
/// ```
/// 
/// # Panics
/// 
/// 当输入为负数时会 panic
/// 
/// ```should_panic
/// use my_crate::factorial;
/// 
/// factorial(-1); // 这会 panic
/// ```
pub fn factorial(n: i32) -> i32 {
    if n < 0 {
        panic!("阶乘不支持负数");
    }
    
    match n {
        0 | 1 => 1,
        _ => n * factorial(n - 1),
    }
}

/// 除法运算
/// 
/// # 参数
/// 
/// * `dividend` - 被除数
/// * `divisor` - 除数
/// 
/// # 返回值
/// 
/// 返回除法结果,如果除数为0则返回错误
/// 
/// # 示例
/// 
/// ```
/// use my_crate::divide;
/// 
/// assert_eq!(divide(10, 2), Ok(5));
/// assert_eq!(divide(10, 3), Ok(3)); // 整数除法
/// ```
/// 
/// # 错误处理
/// 
/// ```
/// use my_crate::divide;
/// 
/// assert!(divide(10, 0).is_err());
/// ```
/// 
/// # 忽略的测试
/// 
/// ```ignore
/// // 这个测试会被忽略
/// use my_crate::divide;
/// 
/// let result = divide(i32::MAX, 1);
/// ```
pub fn divide(dividend: i32, divisor: i32) -> Result<i32, String> {
    if divisor == 0 {
        Err("不能除以零".to_string())
    } else {
        Ok(dividend / divisor)
    }
}

/// 复杂的数据结构示例
/// 
/// ```
/// use std::collections::HashMap;
/// 
/// let mut map = HashMap::new();
/// map.insert("key1", "value1");
/// map.insert("key2", "value2");
/// 
/// assert_eq!(map.get("key1"), Some(&"value1"));
/// assert_eq!(map.get("key3"), None);
/// ```
pub fn example_with_dependencies() {
    // 函数实现
}

文档注释的特殊标记

rust
/// 网络请求函数
/// 
/// # Safety
/// 
/// 这个函数使用了 unsafe 代码,调用者需要确保传入的指针有效
/// 
/// # Errors
/// 
/// 当网络连接失败时返回错误:
/// 
/// - `NetworkError::Timeout` - 连接超时
/// - `NetworkError::ConnectionRefused` - 连接被拒绝
/// 
/// # Panics
/// 
/// 当 URL 格式不正确时会 panic
/// 
/// # Examples
/// 
/// ```no_run
/// // 这个例子不会在测试时运行
/// use my_crate::fetch_data;
/// 
/// let data = fetch_data("https://api.example.com/data").await?;
/// println!("获取到数据: {:?}", data);
/// ```
/// 
/// # See also
/// 
/// * [`process_data`] - 处理获取到的数据
/// * [`validate_url`] - 验证 URL 格式
pub async fn fetch_data(url: &str) -> Result<String, NetworkError> {
    // 实现网络请求
    Ok("模拟数据".to_string())
}

#[derive(Debug)]
pub enum NetworkError {
    Timeout,
    ConnectionRefused,
}

🔧 条件编译注释

配置相关的注释

rust
/// 平台特定的功能
/// 
/// 这个函数在不同平台上有不同的实现
/// 
/// # 平台支持
/// 
/// - Windows: 完全支持
/// - Linux: 完全支持  
/// - macOS: 部分支持
/// 
/// # 示例
/// 
/// ```
/// use my_crate::platform_specific_function;
/// 
/// #[cfg(target_os = "windows")]
/// {
///     // Windows 特定的代码
///     platform_specific_function();
/// }
/// ```
#[cfg(target_os = "windows")]
pub fn platform_specific_function() {
    // Windows 实现
    println!("Windows 版本");
}

#[cfg(target_os = "linux")]
pub fn platform_specific_function() {
    // Linux 实现
    println!("Linux 版本");
}

#[cfg(target_os = "macos")]
pub fn platform_specific_function() {
    // macOS 实现
    println!("macOS 版本");
}

/// 开发时的调试功能
/// 
/// 这个函数只在调试模式下可用
/// 
/// # 注意
/// 
/// 在发布版本中这个函数不存在
/// 
/// # 示例
/// 
/// ```
/// #[cfg(debug_assertions)]
/// use my_crate::debug_function;
/// 
/// #[cfg(debug_assertions)]
/// debug_function();
/// ```
#[cfg(debug_assertions)]
pub fn debug_function() {
    println!("调试信息");
}

📝 注释的最佳实践

良好的注释习惯

rust
/// 用户认证服务
/// 
/// 提供用户登录、注册、密码重置等功能
/// 
/// # 安全考虑
/// 
/// - 密码使用 bcrypt 加密存储
/// - 登录失败次数限制
/// - JWT token 有效期控制
/// 
/// # 示例
/// 
/// ```
/// use auth_service::AuthService;
/// 
/// let auth = AuthService::new();
/// let result = auth.login("user@example.com", "password").await;
/// 
/// match result {
///     Ok(token) => println!("登录成功,token: {}", token),
///     Err(e) => println!("登录失败: {}", e),
/// }
/// ```
pub struct AuthService {
    // 私有字段不需要公开文档
    connection_pool: DatabasePool,
    jwt_secret: String,
}

impl AuthService {
    /// 创建新的认证服务实例
    /// 
    /// # 参数
    /// 
    /// * `database_url` - 数据库连接字符串
    /// * `jwt_secret` - JWT 签名密钥
    /// 
    /// # 错误
    /// 
    /// 如果数据库连接失败会返回错误
    pub fn new(database_url: &str, jwt_secret: String) -> Result<Self, AuthError> {
        // 实际实现会连接数据库
        Ok(Self {
            connection_pool: DatabasePool::new(),
            jwt_secret,
        })
    }
    
    /// 用户登录
    /// 
    /// # 参数
    /// 
    /// * `email` - 用户邮箱
    /// * `password` - 用户密码(明文)
    /// 
    /// # 返回值
    /// 
    /// 成功时返回 JWT token,失败时返回错误
    /// 
    /// # 安全注意事项
    /// 
    /// - 密码会在函数内部进行哈希比较
    /// - 登录失败会增加失败计数
    /// - 多次失败会临时锁定账户
    pub async fn login(&self, email: &str, password: &str) -> Result<String, AuthError> {
        // 1. 验证输入参数
        if email.is_empty() || password.is_empty() {
            return Err(AuthError::InvalidInput);
        }
        
        // 2. 查询用户信息
        // let user = self.find_user_by_email(email).await?;
        
        // 3. 验证密码
        // if !self.verify_password(password, &user.password_hash) {
        //     return Err(AuthError::InvalidCredentials);
        // }
        
        // 4. 生成 JWT token
        // self.generate_jwt_token(&user)
        
        // 简化示例
        Ok("jwt_token_here".to_string())
    }
    
    // 私有方法通常不需要详细的文档注释
    // 但可以添加简短的说明
    
    /// 验证密码哈希
    fn verify_password(&self, password: &str, hash: &str) -> bool {
        // 使用 bcrypt 验证密码
        true // 简化示例
    }
    
    /// 生成 JWT token
    fn generate_jwt_token(&self, user_id: u32) -> Result<String, AuthError> {
        // JWT 生成逻辑
        Ok(format!("token_for_user_{}", user_id))
    }
}

// 错误类型也需要文档
/// 认证服务的错误类型
#[derive(Debug)]
pub enum AuthError {
    /// 输入参数无效
    InvalidInput,
    /// 认证凭据无效
    InvalidCredentials,
    /// 数据库连接错误
    DatabaseError,
    /// JWT token 生成失败
    TokenGenerationError,
}

// 简化的类型定义
struct DatabasePool;
impl DatabasePool {
    fn new() -> Self { Self }
}

不好的注释示例

rust
// 不要写这样的注释:

fn bad_comments_example() {
    // 创建变量 x
    let x = 5; // 设置 x 为 5
    
    // 增加 x
    let x = x + 1; // x 等于 x 加 1
    
    // 打印 x
    println!("{}", x); // 输出 x 的值
    
    /*
     * 这个注释太长了,说了很多废话
     * 但是没有提供任何有用的信息
     * 只是重复了代码本身已经表达的内容
     * 这样的注释对理解代码没有帮助
     */
    let y = 10;
}

// 更好的方式:
fn good_comments_example() {
    // 计算用户积分的基础值
    let base_points = 5;
    
    // 添加新用户奖励分数
    let total_points = base_points + 1;
    
    println!("用户总积分: {}", total_points);
    
    // 设置系统默认超时时间(秒)
    let timeout_seconds = 10;
}

🛠️ 文档生成

Cargo 文档命令

bash
# 生成项目文档
cargo doc

# 生成并打开文档
cargo doc --open

# 生成包含私有项的文档
cargo doc --document-private-items

# 生成依赖项文档
cargo doc --no-deps

# 只检查文档示例
cargo test --doc

文档配置

toml
# Cargo.toml 中的文档配置
[package]
name = "my_crate"
version = "0.1.0"
documentation = "https://docs.rs/my_crate"

[package.metadata.docs.rs]
# 启用所有特性
all-features = true
# 设置默认目标
default-target = "x86_64-unknown-linux-gnu"
# 启用 KaTeX 数学公式支持
rustdoc-args = ["--html-in-header", "katex-header.html"]

📝 本章小结

通过本章学习,你应该掌握了:

注释类型

  • ✅ 行注释和块注释的使用
  • ✅ 外部和内部文档注释
  • ✅ 可执行的文档示例
  • ✅ 特殊标记和条件编译

文档最佳实践

  • ✅ 编写清晰有用的注释
  • ✅ 提供完整的示例代码
  • ✅ 正确使用文档标记
  • ✅ 生成和发布文档

避免的问题

  1. 不要重复代码逻辑
  2. 避免过时的注释
  3. 不要注释显而易见的内容
  4. 保持注释与代码同步

继续学习下一章 - Rust 函数

本站内容仅供学习和研究使用。