函数参数不满足特征界限

Trait bound not satisfied in function argument

我 运行 遇到了特征边界问题,无法理解我做错了什么。我正在使用来自 avr-hal 的 arduino-uno crate,我有一个读取 ADC 的函数,实现如下:

fn read_signal<T: avr_hal_generic::hal::adc::Channel<board::adc::Adc, ID = u8>>(
    adc: &mut board::adc::Adc,
    pinA0: &mut T,
) {
    let x = adc.read(&mut pinA0);
}

但是,我收到以下错误:

the trait bound `&mut T: avr_hal_generic::embedded_hal::adc::Channel<arduino_uno::adc::Adc>` is not satisfied
required because of the requirements on the impl of `arduino_uno::prelude::_embedded_hal_adc_OneShot<arduino_uno::adc::Adc, _, &mut T>` for `arduino_uno::adc::Adc` rustc(E0277)

我试过使用 where 代替,但这没有帮助。我该如何解决这个问题?

另外,虽然我展示了这个具体的例子,但我真的很感激解释或指向关于这个 subject/error 的更好文档的指针,因为我遇到过几次并且很难理解哪里出了问题。

编译器错误说:

the trait bound &mut T: avr_hal_generic::embedded_hal::adc::Channel<arduino_uno::adc::Adc> is not satisfied

请注意,错误要求 &mut T 实现 Channel&mut T: Channel<...>,而您的 T 具有约束 T: Channel<...> — 应用于 T 本身而不是 &mut T。这就是为什么你已经写的界限没有帮助。

现在,正确的解决方法是什么?如果我查看您链接的文档,我可以找到 <Adc as OneShot>::read 的类型。 (注意:我从 docs 中复制了文本来构建此片段;我没有阅读源代码。)

impl<WORD, PIN> OneShot<Adc, WORD, PIN> for Adc
where
    WORD: From<u16>,
    PIN: Channel<Adc, ID = MUX_A>,       // <---- look here
{
    pub fn read(
        &mut self,
        _pin: &mut PIN                   // <---- look here
    ) -> Result<WORD, ...>
}

因此,read 应该被赋予 &mut PIN 并且类型变量 PIN 应该实现 Channel。这一切听起来都很合理,但是在您的代码中 编译器认为我们希望&mut T 实现Channel。出现了额外的 &mut。它从哪里来的?您写道:

fn read_signal<T: avr_hal_generic::hal::adc::Channel<board::adc::Adc, ID = u8>>(
    adc: &mut board::adc::Adc,
    pinA0: &mut T,
) {
    let x = adc.read(&mut pinA0);
}

pinA0&mut T 类型,但是你写了 adc.read(&mut pinA0),这意味着 read() 的参数是 &mut &mut T 类型。由于 read 想要 &mut 实现 Channel 的东西,这会导致您看到的错误,要求 &mut T: Channel.

然后,解决方法是不使用 &mut of &mut:

    let x = adc.read(pinA0);

在某些情况下,Rust 提供 implicit coercions,特别是,它会将对引用的引用(或对实现 Deref 的 'smart pointer' 类型的引用)转换为引用.这就是为什么您过去可能有过无关的 &&mut 工作。然而,当没有一个预期的具体类型时,这些强制转换不会被应用,例如在这种情况下,函数参数的类型包含类型变量 T.