Rust 纯净代码:优雅高效地编写

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么 Rust 纯净代码不是奢侈品,而是必需品

\n\n

Rust 是一种对开发者要求严格的语言。这里的编译器严格但公正:它不容忍内存上的粗心大意,但作为回报,它提供了惊人的速度和安全性。然而,要真正释放 Rust 的潜力,仅仅让代码通过编译是不够的。你需要编写 纯净代码——清晰、可维护且优雅的代码。

\n\n

在本文中,我们将探讨如何编写 Rust 纯净代码,让你的项目不会变成由 unsafe 块和复杂泛型构成的迷宫。你将了解命名原则、所有权管理的惯用法、错误处理以及代码结构。我们开始吧!

\n\n

1. 命名:用 Rust 的语言说话

\n\n

正确的命名是成功的一半。Rust 有严格的约定,违反这些约定就像在 code review 中挥舞红布一样(尤其引人注目)。

\n\n

基本规则

\n
    \n
  • 变量、函数、方法和模块使用 snake_case。
  • \n
  • 类型(struct、enum、trait)使用 PascalCase。
  • \n
  • 常量和静态变量使用 SCREAMING_SNAKE_CASE。
  • \n
\n\n

示例:

\n\n
// 不好\nlet UserName = "Alice";\nfn GetUserData() {}\nconst MAX_SIZE: u32 = 100;\n\n// 好\nlet user_name = "Alice";\nfn get_user_data() {}\nconst MAX_SIZE: u32 = 100;
\n\n

避免缩写(除非显而易见)

\n

与其写 calc_avg(),不如写 calculate_average()。与其用 tmp,不如用 temp_buffer。Rust 鼓励可读性,而非简洁性。

\n\n

建议:如果你编写一个接受闭包的函数,请使用名称 f、g 或 closure——这是普遍接受的做法。

\n\n

2. 所有权与借用:与编译器友好相处

\n\n

所有权系统是 Rust 的核心。纯净代码尊重 ownership 和 borrowing 的规则,不会试图通过不必要的 clone() 或 Rc 来绕过它们。

\n\n

规则:优先选择借用而非所有权

\n

如果函数不需要获取所有权,请接受引用 &T 或可变引用 &mut T。

\n\n
// 不好:多余的 clone\nfn process(data: Vec<i32>) {\n    let mut sum = 0;\n    for &val in &data {\n        sum += val;\n    }\n    println!("Sum: {}", sum);\n}\n\n// 好:借用\nfn process(data: &[i32]) {\n    let mut sum = 0;\n    for &val in data {\n        sum += val;\n    }\n    println!("Sum: {}", sum);\n}
\n\n

避免过度克隆

\n

如果你需要将数据传递到多个地方,请使用 Rc(用于单线程场景)或 Arc(用于多线程场景)。但不要滥用:对于简单情况,引用就足够了。

\n\n

3. 错误处理:放弃恐慌

\n\n

在 Rust 中,有两种主要的错误处理方式:panic!(不可恢复错误)和 Result<T, E>(可恢复错误)。纯净代码尽可能使用 Result。恐慌是用于真正异常情况(例如除以零)的最后手段。

\n\n

使用 ? 运算符

\n

这是一种将错误向上传播的简洁方式。与其使用冗长的 match,不如这样写:

\n\n
use std::fs::File;\nuse std::io::Read;\n\nfn read_file(path: &str) -> Result<String, std::io::Error> {\n    let mut file = File::open(path)?;\n    let mut contents = String::new();\n    file.read_to_string(&mut contents)?;\n    Ok(contents)\n}
\n\n

创建自定义错误类型

\n

与其使用 String 作为错误,不如定义一个枚举:

\n\n
#[derive(Debug)]\nenum MyError {\n    Io(std::io::Error),\n    Parse(std::num::ParseIntError),\n}\n\nimpl From<std::io::Error> for My                

博客

书籍推荐