番外-rust参数传递方式

在 Rust 中,方法的参数传递方式非常讲究所有权、借用和可变性。
通过以下几种方式来传递方法的参数:

  1. &self(不可变引用)
  2. &mut self(可变引用)
  3. self(值传递)
  4. 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()); // 输出 10
}
  • 优点:可以共享访问,不会改变原始对象的状态。
  • 限制:不能修改对象的字段。

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); // 输出 11
}
  • 优点:允许修改对象的字段。
  • 限制:当有可变引用时,其他地方不能再访问这个对象(避免数据竞争)。

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(); // `s` 的所有权已转移
println!("{}", v); // 输出 10
// println!("{}", s.value); // 错误:s 的所有权已被转移,无法再访问
}
  • 优点:通过值传递,可以消耗对象,适用于需要“消费”对象的场景。
  • 限制:一旦传递给方法,原始对象不可再访问。

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); // 输出 15
println!("{}", s.value); // 输出 10 (原对象未受影响)
}
  • 优点:允许你修改副本,但不改变原始对象。
  • 限制:会创建副本,因此可能会增加内存开销。

传参场景总结

语法 类型 描述 适用场景
&self 不可变引用 你只能借用对象,不能修改它。 需要读取对象但不修改的情况。
&mut self 可变引用 可以修改对象的字段,但只能在一个地方同时持有可变引用。 需要修改对象的字段时。
self 值传递(所有权转移) 对象的所有权转移到方法中,原对象不可再访问。返回新的对象或消耗原对象。 需要消耗对象并返回新的对象的场景。
mut self 可变的值传递(副本) 创建对象的可变副本,在副本上进行修改,不影响原对象。 在方法中修改对象的副本,但不影响原始对象。

设计原则

  1. &self:用于方法不修改对象时,优先使用不可变引用,保证对象不被意外修改。
  2. &mut self:用于方法修改对象时,使用可变引用,明确指出该方法会修改对象的状态。
  3. self:用于获取对象所有权的场景,适用于“消耗”对象并返回新对象的情况。
  4. mut self:用于需要修改副本的场景,通常不推荐在不必要时使用,以避免不必要的性能开销。
posted @   代码世界faq  阅读(7)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 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】
点击右上角即可分享
微信分享提示