类型参数“T”不受 impl 特征、自身类型或谓词的约束

Ren*_*mez 8 traits rust

当特征具有相关类型时,我很难理解特征的使用。

这是一个非常简单的例子:

pub trait Message {}

pub trait SendsMessages {
    type Message: Message;
    
    fn send(msg: Self::Message);
}

pub struct ImplementsSendsMessages {

}

impl<T> SendsMessages for ImplementsSendsMessages
where
    T: Message,
{
    type Message = T;

    fn send(id: T) {
        todo!()
    }
}
Run Code Online (Sandbox Code Playgroud)

谁能指出我做错了什么?

Kev*_*eid 16

每当您编写 时impl<T>,您都在定义一个通用实现 \xe2\x80\x94\xc2\xa0a 系列可能的实现。对于您可以填写的每种类型T,这是不同的实现。

\n

但是每个特征实现都必须能够从特征和实现类型中唯一地识别出来:你不能有多个特征 SendsMessages for ImplementsSendsMessages,而这就是你的代码试图创建的。

\n

您可以使用类型参数而不是关联类型来定义特征:

\n
pub trait Message {}\n\npub trait SendsMessages<M: Message> {\n    fn send(msg: M);\n}\n\npub struct ImplementsSendsMessages {}\n\nimpl<T> SendsMessages<T> for ImplementsSendsMessages\nwhere\n    T: Message,\n{\n    fn send(id: T) {\n        todo!()\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是可以接受的,因为每个存在的特征 都有不同,所以它是明确的。SendsMessages<T>T

\n

(如果你有 ,它也会起作用struct ImplementsSendsMessage<T>,因为这也是明确的。)

\n

另一种看待这个问题的方法是,与类型参数相反,关联类型的目的是 \xe2\x80\x9coutputs\xe2\x80\x9d,而不是 \xe2\x80\x9cinputs\xe2\x80\x9d:一次您选择一个特征、一个实现类型,并填写所有参数,关联的类型始终是已知的且唯一的。您的代码失败,因为它尝试用 \xe2\x80\x9canything\xe2\x80\x9d 填充关联类型,而它必须是单个具体类型。

\n