将类型约束应用于与通用功能相关的性状相关类型

时间:2020-08-07 14:23:27

标签: rust embedded stm32

我正在使用与embedded_hal接口(尤其是stm32f4xx-hal)兼容的硬件抽象层,在Rust中为STM32 cortex-m微控制器开发应用程序。

我想实现一个冗长的读取功能,该功能可打印出通用串行端口上收到的内容,并在出错时显示额外的消息。

我的初稿如下:

fn read<T: embedded_hal::serial::Read<u8>>(port: &mut T) {
    match nb::block!(port.read()) {
        Ok(byte) => hprintln!("received {}", byte),
        Err(hal::serial::Error::Overrun) => hprintln!("Overrun Error"),
        Err(_) => hprintln!("Unknown error"),
    }.ok();
}

不幸的是,编译器抱怨无法将序列Error枚举与与Error特性相关联的Read类型调和:

error[E0308]: mismatched types
  --> src/peripherals/cctalk.rs:95:13
   |
93 |     match nb::block!(port.read()) {
   |           ----------------------- this expression has type `core::result::Result<u8, <T as embedded_hal::serial::Read<u8>>::Error>`
94 |         Ok(byte) => hprintln!("received {}", byte),
95 |         Err(hal::serial::Error::Overrun) => hprintln!("Overrun Error"),
   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected associated type, found enum `stm32f4xx_hal::serial::Error`
   |
   = note: expected associated type `<T as embedded_hal::serial::Read<u8>>::Error`
                         found enum `stm32f4xx_hal::serial::Error`
help: consider constraining the associated type `<T as embedded_hal::serial::Read<u8>>::Error` to `stm32f4xx_hal::serial::Error`
   |
92 | fn read<T: embedded_hal::serial::Read<u8, Error = stm32f4xx_hal::serial::Error>>(port: T) {
   | 

在这一点上,我认为应该为特征指定一个附加约束:

fn read<T: embedded_hal::serial::Read<u8>>(port: &mut T) {
// Read::Error must be equal to hal::serial::Error
where <T as embedded_hal::serial::Read<u8>>::Error = hal::serial::Error,
{
    match nb::block!(port.read()) {
        Ok(byte) => hprintln!("received {}", byte),
        Err(hal::serial::Error::Overrun) => hprintln!("Overrun Error"),
        Err(_) => hprintln!("Unknown error"),
    }.ok();
}

这时出现错误,指出在where子句中尚不支持相等约束。

error: equality constraints are not yet supported in `where` clauses
  --> src/peripherals/cctalk.rs:94:1
   |
94 | <T as embedded_hal::serial::Read<u8>>::Error = hal::serial::Error,
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not supported
   |
   = note: see issue #20041 <https://github.com/rust-lang/rust/issues/20041> for more information
help: if `Error` is an associated type you're trying to set, use the associated type binding syntax
   |
94 | T: embedded_hal::serial::Read<u8, Error = hal::serial::Error>,
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

在这里,我对Rust的有限经验不足。我知道应该以某种方式使embedded_hal::serial::Read<u8>::Errorhal::serial::Error相同,但是我不确定(如果可能)如何。我应该如何进行?

1 个答案:

答案 0 :(得分:1)

尽管特征Read的{​​{1}}没有参数,但可以使用以下语法约束关联的Error类型:

Error

在撰写本文时, /*Associated types can be referred to between angular braces like this, similarly to struct fields.*/ fn read<T: embedded_hal::serial::Read<u8, Error = hal::serial::Error>>(port: &mut T) // ... 1.45.0中没有办法在相应的rustc子句中满足此要求。

相关问题