首页 > 解决方案 > 函数参数中不满足特征界限

问题描述

我遇到了特征界限的问题,无法理解我做错了什么。我正在使用来自 avr-hal 的arduino-uno板条箱,并且我有一个读取 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,但这无济于事。我怎样才能解决这个问题?

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

标签: rustavrhal

解决方案


编译器错误说:

特征界限&mut T: avr_hal_generic::embedded_hal::adc::Channel<arduino_uno::adc::Adc>不满足

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

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

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);
}

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

那么,解决方法是不&mut采取&mut

    let x = adc.read(pinA0);

在某些情况下,Rust 提供了隐式强制转换,特别是将引用(或对“智能指针”类型实现Deref的引用)的引用转换为引用。这就是为什么您过去可能有无关&&mut工作的原因。但是,当没有预期的单个具体类型时,不会应用这些强制,例如在这种情况下,函数参数的类型包含类型变量T


推荐阅读