首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当一个对象可能实现多个特征时,如何创建对特征的引用结构?

当一个对象可能实现多个特征时,如何创建对特征的引用结构?
EN

Stack Overflow用户
提问于 2017-08-06 16:56:32
回答 1查看 634关注 0票数 1

我有一个管理多个传感器的结构。我有陀螺仪,加速度计,磁强计,气压计和温度计。所有这些都是特征。

代码语言:javascript
复制
pub struct SensorManager {
    barometer: Barometer + Sized,
    thermometer: Thermometer + Sized,
    gyroscope: Gyroscope + Sized,
    accelerometer: Accelerometer + Sized,
    magnetometer: Magnetometer + Sized
}

我需要使它模块化,以便在配置文件中,您可以指定您正在使用的传感器。

问题是有些传感器重叠。例如:一个人可以有一个包含陀螺仪、加速度计和磁强计的LSM9DS0,而另一个人可以有一个L3GD20陀螺仪和一个LSM303D加速度计,磁强计。

在C++中,我会存储指针或引用,但我不知道如何在Rust中安全地实现这一点。

短版本:需要引用每个传感器作为此结构的成员。其中一些引用具有相同的对象。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-06 17:21:32

在C++中,我会存储指针或引用

铁锈不是外星人。你也做同样的事。主要的区别在于,锈蚀会阻止你通过两条不同的路径变异一件东西,或者有一个悬挂在空中的引用。

回答您的问题有的许多潜在的解决方案。例如,您没有描述您是否需要能够对传感器进行变异,或者描述传感器是否会超过管理器、是否涉及线程等等。所有这些都会影响到微优化代码的性能。

最灵活的解决办法是:

  1. 使用https://doc.rust-lang.org/std/rc/index.html,如RcArc提供的。这允许多个东西拥有传感器。
  2. 使用https://doc.rust-lang.org/std/cell/index.html,如RefCellMutex提供的。这将从编译时到运行时一次执行单个变异引用。
  3. 在决定在运行时使用什么具体对象时,使用https://doc.rust-lang.org/stable/book/ch17-02-trait-objects.html对动态调度进行建模。
代码语言:javascript
复制
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();
}

游乐场上的完整示例

气压计:气压计+大小,

你真的不想这么做。Barometer既是特性,也是类型,但该类型没有大小。它总是需要在指针后面引用(&BarometerBox<Barometer>RefCell<Barometer>等)。

另请参阅:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45534394

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档