2017-08-06 11 views
1

私はいくつかのセンサーを管理する構造体を持っています。私はジャイロスコープ、加速度計、磁力計、気圧計、温度計を持っています。そのすべてが特質です。1つのオブジェクトが複数の形質を実装している場合、どのようにして形質の参照構造を作成できますか?

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

構成ファイルでモジュール式にする必要がありますので、使用するセンサーを指定できます。

問題は、一部のセンサーが重なっていることです。たとえば、ジャイロスコープ、加速度計、磁力計を搭載したLSM9DS0と、L3GD20ジャイロスコープとLSM303D加速度計を搭載した人がいます。

私はポインタや参照を格納しますが、これをRustで正しく実装する方法がわかりません。

短いバージョン:このセンサーのメンバーとして各センサーへの参照が必要です。これらの参照の一部は同じオブジェクトです。

答えて

1

C++では、私は

錆がその外国人ではないポインタや参照を格納します。あなたは同じことをする。主な違いは、Rustはあなたが2つの異なるパスを介して1つのものを突然変異させることができないこと、またはぶら下がっている参照を持つことができないことです。

質問に答える多くの潜在的な解決策があります。たとえば、センサーを突然変異させる必要があるかどうか、スレッドが関与するかどうかなど、センサーがマネージャーよりも長く続くかどうかを記述する必要があるかどうかは記述されていません。 。例えばRc又はArcによって提供されるような

  1. 使用shared ownership

    最大限可撓性溶液がです。これにより、複数のものがセンサーを所有することができます。

  2. interior mutabilityのようなもの、RefCellまたはMutexによって提供されるようなものを使用する。これにより、コンパイル時から実行時まで、一度に1つの変異参照を強制的に実行します。

  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は、形質タイプの両方であるが、タイプはサイズがない。常にポインタの後ろで参照する必要があります(&BarometerBox<Barometer>RefCell<Barometer>など)

関連する問題