番外-rust参数传递方式
在 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()); // 输出 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 |
可变的值传递(副本) | 创建对象的可变副本,在副本上进行修改,不影响原对象。 | 在方法中修改对象的副本,但不影响原始对象。 |
设计原则
&self:用于方法不修改对象时,优先使用不可变引用,保证对象不被意外修改。&mut self:用于方法修改对象时,使用可变引用,明确指出该方法会修改对象的状态。self:用于获取对象所有权的场景,适用于“消耗”对象并返回新对象的情况。mut self:用于需要修改副本的场景,通常不推荐在不必要时使用,以避免不必要的性能开销。

浙公网安备 33010602011771号