在 Rust 中,方法的参数传递方式非常讲究所有权、借用和可变性。
通过以下几种方式来传递方法的参数:
&self
(不可变引用)
&mut self
(可变引用)
self
(值传递)
mut self
(可变的值传递)
1. &self
— 不可变引用
- 语法:
fn method(&self)
- 说明:
&self
是不可变的引用,这意味着方法可以借用对象,但不能修改它。你只能读取对象的内容。
- 使用场景:适用于你只需要读取数据,且不希望修改对象的情况。
示例:
| struct MyStruct { |
| value: i32, |
| } |
| |
| impl MyStruct { |
| fn get_value(&self) -> i32 { |
| self.value |
| } |
| } |
| |
| fn main() { |
| let s = MyStruct { value: 10 }; |
| println!("{}", s.get_value()); |
| } |
- 优点:可以共享访问,不会改变原始对象的状态。
- 限制:不能修改对象的字段。
2. &mut self
— 可变引用
- 语法:
fn method(&mut self)
- 说明:
&mut self
是一个可变引用,意味着你可以在方法中修改对象的内部状态。方法获得对象的可变借用。
- 使用场景:适用于你需要修改对象的场景。
示例:
| struct MyStruct { |
| value: i32, |
| } |
| |
| impl MyStruct { |
| fn increment(&mut self) { |
| self.value += 1; |
| } |
| } |
| |
| fn main() { |
| let mut s = MyStruct { value: 10 }; |
| s.increment(); |
| println!("{}", s.value); |
| } |
- 优点:允许修改对象的字段。
- 限制:当有可变引用时,其他地方不能再访问这个对象(避免数据竞争)。
3. self
— 值传递(获取所有权)
- 语法:
fn method(self)
- 说明:
self
是值传递的意思,调用方法时会转移所有权。这意味着原始对象将被“消耗”,而方法会返回一个新的对象或者完全消耗掉原对象。
- 使用场景:适用于你希望“消耗”对象,进行一些操作后返回一个新的对象的情况。
示例:
| struct MyStruct { |
| value: i32, |
| } |
| |
| impl MyStruct { |
| fn take_ownership(self) -> i32 { |
| self.value |
| } |
| } |
| |
| fn main() { |
| let s = MyStruct { value: 10 }; |
| let v = s.take_ownership(); |
| println!("{}", v); |
| |
| } |
- 优点:通过值传递,可以消耗对象,适用于需要“消费”对象的场景。
- 限制:一旦传递给方法,原始对象不可再访问。
4. mut self
— 可变的值传递
- 语法:
fn method(mut self)
- 说明:
mut self
也是值传递的意思,但它传递的是一个可变的副本。这意味着你获得的是原始对象的副本,你可以在副本上进行修改,但原始对象不会受影响。
- 使用场景:适用于你想要在方法中修改副本,而不影响原始对象的场景。
示例:
| struct MyStruct { |
| value: i32, |
| } |
| |
| impl MyStruct { |
| fn change_value(mut self) -> i32 { |
| self.value += 5; |
| self.value |
| } |
| } |
| |
| fn main() { |
| let s = MyStruct { value: 10 }; |
| let new_value = s.change_value(); |
| println!("{}", new_value); |
| println!("{}", s.value); |
| } |
- 优点:允许你修改副本,但不改变原始对象。
- 限制:会创建副本,因此可能会增加内存开销。
传参场景总结
语法 |
类型 |
描述 |
适用场景 |
&self |
不可变引用 |
你只能借用对象,不能修改它。 |
需要读取对象但不修改的情况。 |
&mut self |
可变引用 |
可以修改对象的字段,但只能在一个地方同时持有可变引用。 |
需要修改对象的字段时。 |
self |
值传递(所有权转移) |
对象的所有权转移到方法中,原对象不可再访问。返回新的对象或消耗原对象。 |
需要消耗对象并返回新的对象的场景。 |
mut self |
可变的值传递(副本) |
创建对象的可变副本,在副本上进行修改,不影响原对象。 |
在方法中修改对象的副本,但不影响原始对象。 |
设计原则
&self
:用于方法不修改对象时,优先使用不可变引用,保证对象不被意外修改。
&mut self
:用于方法修改对象时,使用可变引用,明确指出该方法会修改对象的状态。
self
:用于获取对象所有权的场景,适用于“消耗”对象并返回新对象的情况。
mut self
:用于需要修改副本的场景,通常不推荐在不必要时使用,以避免不必要的性能开销。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】