具有泛型类型的结构的值的结构

时间:2019-06-24 01:29:44

标签: generics struct rust i2c

假设我有一个使用通用类型的struct(BNO055是传感器):

pub struct BNO055<T: I2CDevice + Sized> {
    pub i2cdev: T,
    pub mode: BNO055OperationMode,
}

我还有另一个struct,它以BNO055作为字段:

pub struct IMU {
    device: bno055::BNO055
}

尝试编译此代码会导致错误,编译器会说:

error[E0107]: wrong number of type arguments: expected 1, found 0
   --> src/modules/sensors/imu.rs:553:13
    |
553 |     device: bno055::BNO055
    |             ^^^^^^^^^^^^^^ expected 1 type argument

如果我将通用类型添加到struct,就像这样:

pub struct IMU<D: I2CDevice + Sized>{
    device: bno055::BNO055<D>
}

然后是impl一个函数:

impl<D: I2CDevice + Sized> IMU<D> {
    pub fn init(imu_addr: u16) -> Self {
        let mut i2c_dev = LinuxI2CDevice::new("/dev/i2c-1", imu_addr).unwrap();
        let mut imu_dev = bno055::BNO055::new(i2c_dev).unwrap();

        IMU {
            device: imu_dev
        }
    }
}

我收到此错误:

error[E0308]: mismatched types
   --> src/modules/sensors/imu.rs:567:21
    |
567 |             device: imu_dev
    |                     ^^^^^^^ expected type parameter, found struct `modules::sensors::imu::bno055::i2cdev::linux::LinuxI2CDevice`
    |

imu_dev的类型为BNO055,所以我认为它应该适当地适应泛型的约束。如何解决此错误?

1 个答案:

答案 0 :(得分:2)

init()函数应该为调用方指定的任何IMU<D>创建一个D实例(提供的D满足I2CDevice + Sized的范围):< / p>

impl<D: I2CDevice + Sized> IMU<D> {
    pub fn init(imu_addr: u16) -> Self {

...但是它总是尝试返回一个IMU<LinuxI2CDevice>

(edit)在我的测试中,error[E0308]: mismatched types在其后的注释中进行了解释,该注释应如下所示:

note: expected type `......::BNO055<D>`
         found type `......::BNO055<LinuxI2CDevice>`

(/ edit)

要解决此问题,您可以将init()设为非通用,例如通过将impl更改为impl IMU<LinuxI2CDevice>

P.S。您将BNO055称为“类型”,并试图将其用作类型...我不确定术语,但是请注意,在将某个结构定义为某个类型参数{{1} },仅结构名称并不代表具体类型,而是一族相关但不兼容的类型。您必须提供某种类型来代替D:另一种类型参数D或特定类型BNO055<T>-才能获得类型。

请记住使用泛型的替代方法:将BNO055<LinuxI2CDevice>用作枚举或将其保留为特征,但将其用作trait object,例如I2CDevice