显示页面讨论过去修订反向链接回到顶部 本页面只读。您可以查看源文件,但不能更改它。如果您觉得这是系统错误,请联系管理员。 ====== 测试与高效 Rust 实践 ====== ===== 编写测试 ===== Rust 内置测试框架,无需额外依赖。 ==== 测试注解 ==== <code rust> #[cfg(test)] mod tests { #[test] fn it_works() { let result = 2 + 2; assert_eq!(result, 4); } #[test] fn it_fails() { panic!("这个测试会失败"); } } </code> ==== 常用断言宏 ==== ^ 宏 ^ 说明 ^ | ''assert!(expr)'' | 断言表达式为 true | | ''assert_eq!(a, b)'' | 断言 a == b | | ''assert_ne!(a, b)'' | 断言 a != b | <code rust> fn add_two(x: i32) -> i32 { x + 2 } #[cfg(test)] mod tests { use super::*; #[test] fn test_add_two() { assert_eq!(4, add_two(2)); assert_ne!(5, add_two(2)); } #[test] fn test_with_message() { let result = add_two(3); assert!( result > 0, "结果应为正数,但得到 {}", result ); } } </code> ==== 测试 panic ==== 用 ''#[should_panic]'' 测试应该 panic 的函数: <code rust> fn divide(a: i32, b: i32) -> i32 { if b == 0 { panic!("除数不能为零"); } a / b } #[cfg(test)] mod tests { use super::*; #[test] #[should_panic(expected = "除数不能为零")] fn test_divide_by_zero() { divide(10, 0); } } </code> ==== 使用 Result 测试 ==== <code rust> #[cfg(test)] mod tests { #[test] fn test_with_result() -> Result<(), String> { if 2 + 2 == 4 { Ok(()) } else { Err("2+2 不等于 4".to_string()) } } } </code> ==== 运行测试 ==== <code> cargo test # 运行所有测试 cargo test test_name # 运行指定测试 cargo test -- --nocapture # 显示 println! 输出 cargo test -- --test-threads=1 # 单线程运行 </code> ===== 常用标准库 Trait ===== ==== 自动派生 ==== <code rust> #[derive(Debug, Clone, PartialEq)] struct Point { x: i32, y: i32, } fn main() { let p1 = Point { x: 0, y: 0 }; let p2 = p1.clone(); println!("{:?}", p1); // Debug 格式化 println!("{}", p1 == p2); // PartialEq 比较 } </code> ==== 格式化 ==== <code rust> use std::fmt; struct Person { name: String, age: u8, } impl fmt::Display for Person { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}({}岁)", self.name, self.age) } } fn main() { let p = Person { name: "小明".into(), age: 25, }; println!("{}", p); // "小明(25岁)" } </code> ===== 条件编译 ===== <code rust> #[cfg(target_os = "windows")] fn platform_function() { println!("这是 Windows 系统"); } #[cfg(target_os = "linux")] fn platform_function() { println!("这是 Linux 系统"); } #[cfg(debug_assertions)] fn debug_only() { println!("仅在调试模式下编译"); } fn main() { platform_function(); // 调试模式下才执行 if cfg!(debug_assertions) { println!("调试模式"); } } </code> ===== 常用实践建议 ===== ==== 使用 Option 和 Result ==== 优先使用 ''Option'' 和 ''Result'' 代替需要 ''null'' 或抛出异常的设计。 ==== 避免 panic! ==== 库代码中避免使用 ''panic!'',返回 ''Result'' 让调用者决定如何处理错误。 ==== 使用迭代器 ==== 优先使用迭代器链式操作代替手写循环,代码更简洁且性能不输手写。 <code rust> // 推荐 let sum: i32 = numbers.iter().filter(|x| x % 2 == 0).sum(); // 不如推荐 let mut sum = 0; for x in &numbers { if x % 2 == 0 { sum += x; } } </code> ==== 命名规范 ==== * 类型、Trait:大驼峰 ''MyStruct'' * 函数、变量、模块:蛇形命名 ''my_function'' * 常量:全大写下划线 ''MAX_VALUE'' ==== 文档注释 ==== <code rust> /// 计算两个数的和 /// /// # 示例 /// /// ``` /// let result = add(2, 3); /// assert_eq!(result, 5); /// ``` fn add(a: i32, b: i32) -> i32 { a + b } </code> ''cargo doc --open'' 生成 HTML 文档。 ===== 本章实践 ===== <code rust> /// 计算斐波那契数列第 n 项(测试驱动开发) fn fib(n: u32) -> u32 { match n { 0 => 0, 1 => 1, _ => fib(n - 1) + fib(n - 2), } } #[cfg(test)] mod tests { use super::*; #[test] fn test_fib() { assert_eq!(fib(0), 0); assert_eq!(fib(1), 1); assert_eq!(fib(2), 1); assert_eq!(fib(3), 2); assert_eq!(fib(10), 55); } #[test] fn test_fib_large() { assert_eq!(fib(20), 6765); } } </code> ===== 本章小结 ===== * ''#[test]'' 注解编写测试,''cargo test'' 运行 * ''assert!''、''assert_eq!''、''assert_ne!'' 断言 * ''#[should_panic]'' 测试错误路径 * ''#[derive(Debug, Clone, PartialEq)]'' 自动派生常用 trait * ''#[cfg]'' 条件编译 * 善用 ''cargo doc''、''cargo test''、''cargo clippy'' 等工具 登录 Detach Close 该主题尚不存在 您访问的页面并不存在。如果允许,您可以使用创建该页面按钮来创建它。 rust/测试与高效实践.txt 最后更改: 2026/06/15 15:44由 张叶安 登录