如何在具有泛型参数的结构上实现非泛型特征 [英] How to implement non-generic trait on a struct with a generic parameter

查看:48
本文介绍了如何在具有泛型参数的结构上实现非泛型特征的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 I2CDevice 特质在外部包装箱中定义,如下所示:

I am using the I2CDevice trait which is defined in an external crate like this:

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

它或其任何成员都不包含任何通用参数.

Neither it nor any of its members contain any generic arguments.

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

I am creating a decorator for any I2CDevice implementation which delegates to an inner/concrete I2CDevice, adding console printing for diagnostic purposes:

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 __ .

I can't figure out what to put in place of __A__ and __B__.

当我不使用任何泛型参数时,会出现编译器错误:预期的1个生存期参数预期的1个类型参数.

When I use no generic arguments whatsoever, I get compiler errors: Expected 1 lifetime parameter and Expected 1 type argument.

然后我的最佳猜测是将 __ A __ 留空,因为 I2CDevice 的定义不需要通用参数,然后镜像用于 debugDeviceDecorator的类型参数结构本身代替 __ B __ ,例如:

My best guess then is to leave __A__ blank because the definition of I2CDevice requires no generic arguments, and then to mirror the type argument used for the debugDeviceDecorator struct itself in place of __B__ like:

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

我收到编译错误:错误:预期为( + :: < > ,发现: 在冒号(:)上,该冒号开始对通用参数 T 施加类型约束.

I get the compilation error: error: expected one of !, (, +, ,, ::, <, or >, found :, which occurs on the colon (:) that begins the type constraint on the generic argument T.

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

Perhaps the compiler thinks that I'm trying to constrain T in a manner which diverges from the constraint in the struct definition itself, so instead I try:

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

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

Which results in the errors undeclared lifetime for the lifetime parameter, and undefined or not in scope for the type argument itself, at which point I cannot figure out how to proceed. I would assume that the lifetime and the type argument are defined by the future, as yet nonexistent code that will some day initialize a debugDeviceDecorator struct, values which cannot yet be known and seem to me as though should not prevent this existing code from compiling.

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

I can see the compiler needing some information about the type of self.device used within the functions of the impl, but I feel like my first guess in which I mirrored the struct's expanded type definition in my impl declaration should have provided that.

推荐答案

您应该重新阅读 Rust编程语言,尤其是

You should re-read The Rust Programming Language, specifically the section on how to implement traits for generic structs. A lot of hard work has gone into that documentation so that people can get started in Rust easier.

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

The book will show you the proper syntax for how to define a trait for a struct:

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

注意:

  1. 在使用它们之前,必须声明两个通用值('a T ).

该特征没有泛型这一事实没什么特别的.

There's nothing special about the fact that the trait has no generics.

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

Types in Rust use PascalCase, not camelCase, so I've changed the name.

我切换到了 where 子句,因为当将边界塞入通用声明时很难读取边界.

I switched to a where clause because it's too hard to read the bounds when they are crammed into the generic declaration.

这篇关于如何在具有泛型参数的结构上实现非泛型特征的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆