【发布时间】: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> { }
我收到编译错误:错误:预期为 !、(、+、,、::、< 或 > 之一,发现 : ,它出现在冒号 (:) 上,该冒号开始对泛型参数 T 进行类型约束。
也许编译器认为我试图以与结构定义本身的约束不同的方式约束T,所以我尝试:
impl I2CDevice for debugDeviceDecorator<'a, T> {}
这会导致生命周期参数的错误未声明的生命周期,以及类型参数本身的未定义或不在范围内,此时我无法弄清楚如何继续。我会假设生命周期和类型参数是由未来定义的,但不存在的代码有一天会初始化一个 debugDeviceDecorator 结构,这些值尚不为人所知,在我看来似乎不应该阻止这个现有的代码编译。
我可以看到编译器需要一些关于 impl 函数中使用的 self.device 类型的信息,但我觉得我在 impl 声明中镜像结构的扩展类型定义的第一个猜测应该提供了.
【问题讨论】:
-
@ardave 仅供参考,您可以在
impl和I2CDevice之间添加一些内容。 -
出现在以冒号 (:) 开头的类型约束 — 为什么你会特意用英语重新输入什么通过简单地复制粘贴错误可以更清楚地表达?