MST

星途 面试题库

面试题:Rust中self与&self、&mut self的区别及应用场景

详细说明Rust中self、&self和&mut self的语义区别,在实际项目开发中,什么样的功能需求会分别用到这三种不同形式的self?请通过代码示例分别展示它们的用法及适用场景。
23.1万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试

语义区别

  1. self
    • 语义:获取所有权。当方法签名使用self时,调用该方法后,self的所有权会转移到方法内部,意味着原变量在方法调用后不再可用。
  2. &self
    • 语义:不可变借用。&self表示以不可变引用的方式借用self,在方法内部不能修改self所指向的数据,多个&self可以同时存在。
  3. &mut self
    • 语义:可变借用。&mut self表示以可变引用的方式借用self,在方法内部可以修改self所指向的数据,但同一时间只能有一个&mut self存在,以避免数据竞争。

实际项目中的功能需求及代码示例

  1. 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方法中
}
  1. &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);
}
  1. &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);
}