MST

星途 面试题库

面试题:Rust浅拷贝和深拷贝的场景判断

在Rust中,假设有一个自定义结构体`Person`,包含一个`String`类型的名字字段`name`和一个`u32`类型的年龄字段`age`。现在有一个需求,需要创建多个`Person`实例,这些实例共享部分数据以节省内存,但名字又能独立修改,请问在这种情况下应选择浅拷贝还是深拷贝,并说明如何实现。
48.7万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
  1. 选择浅拷贝
    • 因为需求是共享部分数据以节省内存,浅拷贝只复制指针等元数据,而不是数据本身,符合共享数据节省内存的要求。同时名字要能独立修改,后续可以通过RcRefCell的组合来实现对共享数据中可变部分(这里是name)的修改。
  2. 实现步骤
    • 首先,定义Person结构体并使用Rc(引用计数)和RefCell(内部可变性)来实现。
    use std::cell::RefCell;
    use std::rc::Rc;
    
    struct Person {
        name: Rc<RefCell<String>>,
        age: u32,
    }
    
    impl Person {
        fn new(name: String, age: u32) -> Self {
            Person {
                name: Rc::new(RefCell::new(name)),
                age,
            }
        }
    }
    
    fn main() {
        let person1 = Person::new("Alice".to_string(), 30);
        let person2 = Person {
            name: person1.name.clone(),
            age: 35,
        };
    
        // 修改person1的名字
        {
            let mut name1 = person1.name.borrow_mut();
            *name1 = "Bob".to_string();
        }
    
        // 打印person2的名字,此时会发现共享的名字已经改变
        println!("person2's name: {}", *person2.name.borrow());
    }
    
    • 在上述代码中:
      • Person结构体中的name字段使用Rc<RefCell<String>>类型。Rc用于实现共享数据的引用计数,使得多个Person实例可以共享同一个String数据的指针,从而节省内存。RefCell则提供了内部可变性,允许在不可变引用的情况下修改内部的String
      • main函数中,创建person1实例后,通过clone方法复制person1name字段的Rc指针,从而让person2共享person1name数据。
      • 可以通过borrow_mut方法获取RefCell内部String的可变引用,从而实现对name的修改,并且这种修改会反映在共享该数据的其他实例上。