面试题答案
一键面试- 选择浅拷贝:
- 因为需求是共享部分数据以节省内存,浅拷贝只复制指针等元数据,而不是数据本身,符合共享数据节省内存的要求。同时名字要能独立修改,后续可以通过
Rc
和RefCell
的组合来实现对共享数据中可变部分(这里是name
)的修改。
- 因为需求是共享部分数据以节省内存,浅拷贝只复制指针等元数据,而不是数据本身,符合共享数据节省内存的要求。同时名字要能独立修改,后续可以通过
- 实现步骤:
- 首先,定义
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
方法复制person1
的name
字段的Rc
指针,从而让person2
共享person1
的name
数据。 - 可以通过
borrow_mut
方法获取RefCell
内部String
的可变引用,从而实现对name
的修改,并且这种修改会反映在共享该数据的其他实例上。
- 首先,定义