在C++中,我会存储指针或引用
锈并不是那么陌生。你做同样的事情。主要的区别在于,锈蚀阻止你通过两条不同的路径变异一件事,或者有一个悬而未决的引用。
回答你的问题
许多的
最灵活的解决方案是:
-
使用
shared ownership
,例如
Rc
Arc
-
使用
interior mutability
,例如
RefCell
或
Mutex
-
trait objects
对动态调度进行建模,因为在运行时决定使用哪些具体对象。
use std::{cell::RefCell, rc::Rc};
trait Barometer {
fn get(&self) -> i32;
fn set(&self, value: i32);
}
trait Thermometer {
fn get(&self) -> i32;
fn set(&self, value: i32);
}
trait Gyroscope {
fn get(&self) -> i32;
fn set(&self, value: i32);
}
struct Multitudes;
impl Barometer for Multitudes {
fn get(&self) -> i32 {
1
}
fn set(&self, value: i32) {
println!("Multitudes barometer set to {}", value)
}
}
impl Thermometer for Multitudes {
fn get(&self) -> i32 {
2
}
fn set(&self, value: i32) {
println!("Multitudes thermometer set to {}", value)
}
}
struct AutoGyro;
impl Gyroscope for AutoGyro {
fn get(&self) -> i32 {
3
}
fn set(&self, value: i32) {
println!("AutoGyro gyroscope set to {}", value)
}
}
struct SensorManager {
barometer: Rc<RefCell<dyn Barometer>>,
thermometer: Rc<RefCell<dyn Thermometer>>,
gyroscope: Rc<RefCell<dyn Gyroscope>>,
}
impl SensorManager {
fn new(
barometer: Rc<RefCell<dyn Barometer>>,
thermometer: Rc<RefCell<dyn Thermometer>>,
gyroscope: Rc<RefCell<dyn Gyroscope>>,
) -> Self {
Self {
barometer,
thermometer,
gyroscope,
}
}
fn dump_info(&self) {
let barometer = self.barometer.borrow();
let thermometer = self.thermometer.borrow();
let gyroscope = self.gyroscope.borrow();
println!(
"{}, {}, {}",
barometer.get(),
thermometer.get(),
gyroscope.get()
);
}
fn update(&self) {
self.barometer.borrow_mut().set(42);
self.thermometer.borrow_mut().set(42);
self.gyroscope.borrow_mut().set(42);
}
}
fn main() {
let multi = Rc::new(RefCell::new(Multitudes));
let gyro = Rc::new(RefCell::new(AutoGyro));
let manager = SensorManager::new(multi.clone(), multi, gyro);
manager.dump_info();
manager.update();
}
Complete example on the Playground
barometer: Barometer + Sized,
你真的不想这样。
Barometer
特质
和a
,但类型没有大小。它总是需要在指针后面引用(
&Barometer
Box<Barometer>
,
RefCell<Barometer>