#Rust 注释
#概述
注释是代码中的重要组成部分,用于解释代码逻辑、生成文档、标记待办事项等。Rust 提供了多种注释方式,本章将详细介绍各种注释语法和最佳实践。
#💬 基本注释
#行注释
fn line_comments() {
// 这是一个单行注释
let x = 5; // 行尾注释
// 多行注释可以这样写
// 每一行都需要双斜杠
// 这样的注释很清晰
let y = 10;
// TODO: 实现更复杂的逻辑
// FIXME: 修复这里的性能问题
// NOTE: 这里需要特别注意
// HACK: 临时解决方案
println!("x: {}, y: {}", x, y);
}#块注释
fn block_comments() {
/*
* 这是一个块注释
* 可以跨越多行
* 通常用于大段的注释
*/
let message = "Hello, World!";
/* 简单的块注释 */
let number = 42;
/*
块注释可以嵌套
/*
像这样嵌套
/* 甚至可以多层嵌套 */
*/
*/
println!("{}: {}", message, number);
}#注释中的代码
fn commented_code() {
let active_code = "这行会执行";
// let commented_code = "这行不会执行";
/*
let block_commented = "这些代码";
let all_commented = "都不会执行";
*/
println!("{}", active_code);
}#📚 文档注释
#外部文档注释
/// 计算两个数的和
///
/// # 参数
///
/// * `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('@')
}
}#内部文档注释
//! 这是模块级别的文档注释
//!
//! 这个模块提供了用户管理的功能
//!
//! # 功能
//!
//! - 创建用户
//! - 验证用户信息
//! - 用户数据管理
//!
//! # 使用方法
//!
//! ```
//! 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('@')
}
}#📖 文档示例和测试
#可运行的文档示例
/// 计算阶乘
///
/// # 参数
///
/// * `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() {
// 函数实现
}#文档注释的特殊标记
/// 网络请求函数
///
/// # 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,
}#🔧 条件编译注释
#配置相关的注释
/// 平台特定的功能
///
/// 这个函数在不同平台上有不同的实现
///
/// # 平台支持
///
/// - 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!("调试信息");
}#📝 注释的最佳实践
#良好的注释习惯
/// 用户认证服务
///
/// 提供用户登录、注册、密码重置等功能
///
/// # 安全考虑
///
/// - 密码使用 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 }
}#不好的注释示例
// 不要写这样的注释:
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 文档命令
# 生成项目文档
cargo doc
# 生成并打开文档
cargo doc --open
# 生成包含私有项的文档
cargo doc --document-private-items
# 生成依赖项文档
cargo doc --no-deps
# 只检查文档示例
cargo test --doc#文档配置
# 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"]#📝 本章小结
通过本章学习,你应该掌握了:
#注释类型
- ✅ 行注释和块注释的使用
- ✅ 外部和内部文档注释
- ✅ 可执行的文档示例
- ✅ 特殊标记和条件编译
#文档最佳实践
- ✅ 编写清晰有用的注释
- ✅ 提供完整的示例代码
- ✅ 正确使用文档标记
- ✅ 生成和发布文档
#避免的问题
- 不要重复代码逻辑
- 避免过时的注释
- 不要注释显而易见的内容
- 保持注释与代码同步
继续学习:下一章 - Rust 函数