Rust 的 struct 与方法
用 struct 聚合数据,用 impl 定义方法与关联函数;所有权如何进入字段与 self 接收者。
#type / concept
#status / growing
#tech / dev
#resource / rust
[!info] 关联笔记
Rust 的 struct 与方法
这个概念为什么出现
真实领域对象很少是一两个标量:用户、矩形、订单都需要字段聚合与附着行为。
Rust 用 struct 描述数据形状,用 impl 挂方法与构造器,而不走类继承树。
[!abstract] 一句话理解
struct定义字段布局;impl Type { fn method(&self) ... }提供方法;self/&self/&mut self决定方法如何获取接收者。
最小可运行示例
场景:仓储矩形货位——算面积与放大
WMS 用矩形描述货位占位;需要只读算面积,以及管理员调整尺寸。
// 业务意图:货位矩形面积与缩放。
// 教学点:结构体、关联函数 new、&self / &mut self 方法。
#[derive(Debug)]
struct BinRect {
width_cm: u32,
height_cm: u32,
}
impl BinRect {
// 关联函数:构造器,无 self
fn new(width_cm: u32, height_cm: u32) -> Self {
Self { width_cm, height_cm }
}
// 只读方法
fn area(&self) -> u32 {
self.width_cm * self.height_cm
}
// 可变方法
fn scale(&mut self, factor: u32) {
self.width_cm *= factor;
self.height_cm *= factor;
}
}
fn main() {
let mut bin = BinRect::new(30, 20);
println!("area={}", bin.area());
bin.scale(2);
println!("scaled={bin:?}");
}
建议运行:cargo run
期望输出:
area=600
scaled=BinRect { width_cm: 60, height_cm: 40 }
结合场景再看三个关注点
new是惯例不是关键字area用&self不夺走矩形scale用&mut self就地修改
核心概念与准确模型
结构体形态
- 命名字段 struct
- 元组 struct:
struct Point(i32,i32); - 单元 struct:
struct Marker;
更新语法
let user2 = User { email: String::from("new"), ..user1 };
// 可能 move 未 Copy 字段
方法接收者
| 接收者 | 含义 |
|---|---|
self | 夺走所有权 |
&self | 共享借用 |
&mut self | 可变借用 |
字段若含引用,需要生命周期,见 生命周期。
设计动机
- 数据与行为分离于
struct/impl,可对同一类型多段impl - 无继承:组合字段 + trait 共享行为
- 所有权进入字段,迫使想清“结构体是否拥有其数据”
边界与误区
- 字段默认私有(模块可见性)
..更新可能部分 move- 不要把“类”思维硬套虚函数表——那是 trait 对象议题
[!warning] 常见误区:结构体字段全用引用却不懂生命周期 入门优先拥有型字段(
String而非&str),需要引用再学生命周期。
工程实践
- 构造器验证不变量
- 只读查询
&self,修改&mut self,构建器可self Debug/Clone等 derive 按需- 大结构避免无谓
clone
本节总结
- struct 聚合;impl 提供方法
- 接收者编码所有权
- 组合优于继承
自测题
&self与self方法对调用方的区别?- 为什么字段默认用
String而不是&str?
参考答案
&self调用后对象仍可用;self会 move。- 避免结构体生命周期纠缠,实例独立拥有数据更简单。
延伸阅读与资料来源
| 资料 | 类型 | 支撑内容 |
|---|---|---|
| The Book — Structs | 官方书 | 结构体与方法 |
| The Book — Method Syntax | 官方书 | 方法 |