2017-08-06 83 views
1

我有一個管理多個傳感器的結構。我有一個陀螺儀,加速計,磁力計,氣壓計和溫度計。所有這些都是特質。當一個對象可能實現多個特徵時,如何創建對特徵的引用結構?

pub struct SensorManager { 
    barometer: Barometer + Sized, 
    thermometer: Thermometer + Sized, 
    gyroscope: Gyroscope + Sized, 
    accelerometer: Accelerometer + Sized, 
    magnetometer: Magnetometer + Sized 
} 

我需要使它成爲模塊化的,所以在配置文件中您可以指定您正在使用的傳感器。

問題是一些傳感器重疊。例如:一個人可以有一個包含陀螺儀,加速度計和磁力計的LSM9DS0,而另一個人可以有一個L3GD20陀螺儀和一個LSM303D加速計 - 磁力計。

在C++中,我會存儲指針或引用,但我不確定如何在Rust中安全地正確實現它。

簡短版本:需要將每個傳感器的引用作爲此結構的成員。其中一些參考文獻是同一個對象。

回答

1

在C++中我將存儲指針或引用

鏽是不是外星人。你做同樣的事情。主要區別在於Rust可以防止你能夠通過兩條不同的路徑改變一個事物,或者讓一個引用懸垂起來。

回答你的問題有很多潛在的解決方案。例如,你沒有描述你是否需要能夠改變傳感器或者描述傳感器是否會超過管理器,如果線程會涉及等等。所有這些都會影響代碼的微代碼優化。

的最大靈活的解決方案是:

  1. 使用shared ownership,諸如由RcArc提供。這允許多種東西來擁有傳感器。

  2. 使用interior mutability,例如由RefCellMutex提供的那個。這會在編譯時間到運行時間的某個時間執行單個變更引用。

  3. 使用trait objects來模擬動態調度,因爲在運行時決定使用哪些具體對象。

struct SensorManager { 
    barometer: Rc<RefCell<Barometer>>, 
    thermometer: Rc<RefCell<Thermometer>>, 
    gyroscope: Rc<RefCell<Gyroscope>>, 
} 

impl SensorManager { 
    fn new(
     barometer: Rc<RefCell<Barometer>>, 
     thermometer: Rc<RefCell<Thermometer>>, 
     gyroscope: Rc<RefCell<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.clone(), gyro.clone()); 

    manager.dump_info(); 
    manager.update(); 
} 

Complete example on the Playground


barometer: Barometer + Sized, 

你真的不想要這個。 Barometer既是特徵類型,但該類型沒有大小。它始終需要在指針後面引用(&Barometer,Box<Barometer>,RefCell<Barometer>等)。)

相關問題