引言:为什么 Rust 结构体初始化并不枯燥?
\n\n如果你曾经用 Rust 写过代码,那么你很可能遇到过这样的时刻,想大喊一声:“为什么我必须一遍又一遍地写 field: field?这明明显而易见!”
是的,Rust 是一门严谨、严格且极具表现力的语言。但即便如此,它也为语法糖留出了空间,让代码更简洁、更清晰、更赏心悦目。尤其是在结构体初始化方面——这是我们每天都要做几十次的例行公事。
\n\n在本文中,我们不仅会回答 Stack Overflow 上的热门问题:“有没有更快/更短的方法来初始化 Rust 结构体中的变量?”。我们还将深入探讨所有方法——从基础到高级——并展示如何编写既快速、可读又符合“Rust 风格”(idiomatic Rust)的代码。
\n\n准备好加速你与 Rust struct 的工作了吗?我们开始吧!
\n\n1. 经典方式:显式字段命名
\n\n让我们从基础开始。假设我们有一个结构体 User:
struct User {\n username: String,\n email: String,\n sign_in_count: u64,\n active: bool,\n}\n\n标准的初始化方式如下:
\n\nlet user1 = User {\n email: String::from("someone@example.com"),\n username: String::from("someusername123"),\n active: true,\n sign_in_count: 1,\n};\n\n一切都很诚实,一切都很明确。但是,当你有 10-15 个字段,并且变量名与字段名相同时——这就开始令人烦恼了。你写着 email: email,感觉自己像个填写表格的官僚。
好消息是:Rust 也感受到了这一点。并想出了解决方案。
\n\n2. 字段初始化简写:当变量名与字段名相同时
\n\n从 Rust 1.17 开始,如果变量名与结构体字段名相同,你可以使用简写形式。这被称为 field init shorthand。
\n\nlet email = String::from("someone@example.com");\nlet username = String::from("someusername123");\n\nlet user1 = User {\n email, // 代替 email: email\n username, // 代替 username: username\n active: true,\n sign_in_count: 1,\n};\n\n很漂亮,对吧?Rust 自己就能理解 email 既是变量也是字段。当你传递已经命名得当的函数参数时,这种技巧尤其方便。
何时使用:只要变量名与字段名相同,就使用它。这不仅“写得更快”,更是符合 Rust 风格的写法。
\n\n3. 结构体更新语法:基于现有结构体进行修改
\n\n假设我们已经有了 user1,并且想创建一个 user2,只修改 email。难道必须重写所有字段吗?不!
let user2 = User {\n email: String::from("another@example.com"),\n ..user1 // 其余字段从 user1 获取\n};\n\n.. 操作符就是 struct update syntax。它告诉编译器:“从 user1 中获取所有剩余字段”。重要提示:之后 user1 会被部分移动(如果字段未实现 Copy),所以请注意所有权问题。
当你基于现有数据进行 Rust 结构体初始化 时,这种语法能节省大量代码行。
\n\n4. Default 特质:使用默认值初始化
\n\n如果大多数字段应该有标准值呢?例如,active: true 和 sign_in_count: 0?你可以实现 Default 特质:
#[derive(Default)]\nstruct User {\n username: String,\n email: String,\n active: bool,\n sign_in_count: u64,\n}\n\n// 现在:\nlet user_default = User::default();\n// username: "", email: "", active: false, sign_in_count: 0\n\n但是等等!
博客
书籍推荐
推荐阅读