【问题标题】:How to implement non-generic trait on a struct with a generic parameter如何在具有泛型参数的结构上实现非泛型特征
【发布时间】:2017-03-12 07:07:27
【问题描述】:

我正在使用I2CDevice trait,它在外部 crate 中定义,如下所示:

pub trait I2CDevice {
    type Error: Error;
    // members
}

它及其任何成员都不包含任何通用参数。

我正在为任何I2CDevice 实现创建一个装饰器,它委托给内部/具体I2CDevice,添加控制台打印以用于诊断目的:

struct debugDeviceDecorator<'a, T: I2CDevice<Error = LinuxI2CError> + Sized + 'a> {
    device: &'a mut T,
}

impl I2CDevice__A__ for debugDeviceDecorator__B__ {
    type Error = LinuxI2CError;

    fn read(&mut self, data: &mut [u8]) -> Result<(), Self::Error> {
        println!("read: data: {:?}", data);
        self.device.read(data)
    }

    // etc.
}

我不知道用什么代替 __A____B__

当我不使用任何泛型参数时,我会收到编译器错误:预期 1 个生命周期参数预期 1 个类型参数。

然后我最好的猜测是将__A__留空,因为I2CDevice的定义不需要泛型参数,然后镜像用于debugDeviceDecorator结构本身的类型参数来代替__B__,例如:

impl I2CDevice for debugDeviceDecorator<'a, T: I2CDevice<Error=LinuxI2CError> + Sized + 'a> { }

我收到编译错误:错误:预期为 !(+,::&lt;&gt; 之一,发现 : ,它出现在冒号 (:) 上,该冒号开始对泛型参数 T 进行类型约束。

也许编译器认为我试图以与结构定义本身的约束不同的方式约束T,所以我尝试:

impl I2CDevice for debugDeviceDecorator<'a, T> {}

这会导致生命周期参数的错误未声明的生命周期,以及类型参数本身的未定义或不在范围内,此时我无法弄清楚如何继续。我会假设生命周期和类型参数是由未来定义的,但不存在的代码有一天会初始化一个 debugDeviceDecorator 结构,这些值尚不为人所知,在我看来似乎不应该阻止这个现有的代码编译。

我可以看到编译器需要一些关于 impl 函数中使用的 self.device 类型的信息,但我觉得我在 impl 声明中镜像结构的扩展类型定义的第一个猜测应该提供了.

【问题讨论】:

  • @ardave 仅供参考,您可以在implI2CDevice 之间添加一些内容。
  • 出现在以冒号 (:) 开头的类型约束为什么你会特意用英语重新输入什么通过简单地复制粘贴错误可以更清楚地表达?

标签: generics rust


【解决方案1】:

您应该重新阅读 Rust 编程语言,特别是 how to implement traits for generic structs 部分。 大量 已在该文档中进行了艰苦的工作,以便人们可以更轻松地开始使用 Rust。

本书将向您展示如何为结构定义特征的正确语法:

impl<'a, T> I2CDevice for DebugDeviceDecorator<'a, T>
    where T: I2CDevice<Error = LinuxI2CError> + Sized + 'a
{
    // ...
}

注意:

  1. 您必须先声明两个通用值('aT),然后才能使用它们。

  2. 特征没有泛型这一事实并没有什么特别之处。

  3. Rust 中的类型使用 PascalCase,而不是 camelCase,所以我更改了名称。

  4. 我切换到 where 子句,因为当它们被塞进泛型声明时,很难阅读边界。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多