将类型约束应用于泛型函数的特征关联类型
Applying a Type Constraint to a Trait-associated Type for a Generic Function
我正在 Rust 中为 STM32 cortex-m 微控制器开发应用程序,使用符合 embedded_hal
接口的硬件抽象层 - 具体来说,stm32f4xx-hal
.
我想实现一个详细的读取功能,打印在通用串行端口上接收到的内容,并在出现错误时显示额外的消息。
我的初稿是这样的:
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
枚举与与 Read
特征关联的 Error
类型调和:
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>::Error
与 hal::serial::Error
相同,但我不确定如何(如果可能)。我该如何进行?
尽管特征 Read
没有其 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)
// ...
(在撰写本文时,rustc
1.45.0)无法在相应的 where
子句中处理此要求。
我正在 Rust 中为 STM32 cortex-m 微控制器开发应用程序,使用符合 embedded_hal
接口的硬件抽象层 - 具体来说,stm32f4xx-hal
.
我想实现一个详细的读取功能,打印在通用串行端口上接收到的内容,并在出现错误时显示额外的消息。
我的初稿是这样的:
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
枚举与与 Read
特征关联的 Error
类型调和:
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>::Error
与 hal::serial::Error
相同,但我不确定如何(如果可能)。我该如何进行?
尽管特征 Read
没有其 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)
// ...
(在撰写本文时,rustc
1.45.0)无法在相应的 where
子句中处理此要求。