语义区别
self
:
- 语义:获取所有权。当方法签名使用
self
时,调用该方法后,self
的所有权会转移到方法内部,意味着原变量在方法调用后不再可用。
&self
:
- 语义:不可变借用。
&self
表示以不可变引用的方式借用self
,在方法内部不能修改self
所指向的数据,多个&self
可以同时存在。
&mut self
:
- 语义:可变借用。
&mut self
表示以可变引用的方式借用self
,在方法内部可以修改self
所指向的数据,但同一时间只能有一个&mut self
存在,以避免数据竞争。
实际项目中的功能需求及代码示例
self
的使用场景:
- 功能需求:当方法需要获取对象的所有权并可能对其进行消耗或转移所有权时使用。例如,一个方法将对象转换为另一种类型,并消耗原对象。
- 代码示例:
struct MyString {
data: String,
}
impl MyString {
fn into_inner(self) -> String {
self.data
}
}
fn main() {
let s = MyString { data: "hello".to_string() };
let inner = s.into_inner();
// 这里s不再可用,因为所有权已转移到into_inner方法中
}
&self
的使用场景:
- 功能需求:当方法只需要读取对象的状态,而不需要修改它时使用。例如,计算对象的某个属性值,或者进行基于对象状态的逻辑判断等。
- 代码示例:
struct Point {
x: i32,
y: i32,
}
impl Point {
fn distance_from_origin(&self) -> f64 {
((self.x * self.x + self.y * self.y) as f64).sqrt()
}
}
fn main() {
let p = Point { x: 3, y: 4 };
let dist = p.distance_from_origin();
println!("Distance from origin: {}", dist);
}
&mut self
的使用场景:
- 功能需求:当方法需要修改对象的内部状态时使用。例如,修改对象的某个字段值,或者对对象内部的集合进行添加、删除元素等操作。
- 代码示例:
struct Counter {
count: i32,
}
impl Counter {
fn increment(&mut self) {
self.count += 1;
}
fn get_count(&self) -> i32 {
self.count
}
}
fn main() {
let mut c = Counter { count: 0 };
c.increment();
let count = c.get_count();
println!("Count: {}", count);
}