rust - 如何要求两个特征的关联类型相同?

标签 rust associated-types

<分区>

我有以下两个特点:

trait Filter {
    type Message;
    fn is_valid(&self, message: &Self::Message) -> bool;
}

trait Client {
    type Message;
    fn send(&self, message: &Self::Message) -> Result<(), Error>;
}

我希望 FilterClient 的实现使用相同的 Message 类型。

struct ClientWithFilter<C: Client, F: Filter> {
    filter: F,
    client: C,
}

impl<C: Client, F: Filter> ClientWithFilter<C, F> {
    /// C::Message or F::Message???
    fn check_and_send(&self, message: &C::Message) -> Result<(), Error> {
        if self.filter.is_valid(message) {
            self.client.send(message)
        } else {
            Err(Error::MessageInvalid)
        }
    }
}

这不编译:

if self.filter.is_valid(message) {
    |                   ^^^^^^^ expected client::Filter::Message, found client::Client::Message
    |
    = note: expected type `&<F as client::Filter>::Message`
               found type `&<C as client::Client>::Message`

编译器看到 2 种不同的类型,而我希望只有一种。 我怎样才能以正确的方式用 Rust 编写它?

最佳答案

您需要适本地约束类型参数:

struct ClientWithFilter<C, F>
where
    C: Client,
    F: Filter<Message = C::Message>,
{
    filter: F,
    client: C,
}

impl<C, F> ClientWithFilter<C, F>
where
    C: Client,
    F: Filter<Message = C::Message>,
{
    fn check_and_send(&self, message: &C::Message) -> Result<(), Error> {
        if self.filter.is_valid(message) {
            self.client.send(message)
        } else {
            Err(Error::MessageInvalid)
        }
    }
}

playground

我认为,目前有必要对 impl 的约束进行冗余重复。我相信有一个 RFC 可以让 impls 从结构定义中继承约束。

关于rust - 如何要求两个特征的关联类型相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55135637/

相关文章:

rust - 实现 proc 宏时的循环包依赖

rust - 对于数字类型的 "fuzzy compare",我可以使用什么特征?

Swift 关联类型约束

rust - 将Box与nom解析器一起使用时出现神秘错误 “one type is more general than the other”

rust - 如何在 Rust 的内置函数上实现特征?

rust - Rust 项目中的工作区内依赖关系

haskell - 我们如何在保持类型安全的同时通用地处理关联类型

Swift:类型别名和协议(protocol)中具有值的关联类型有什么区别?

swift - 在 Swift 中使用具有约束关联类型的协议(protocol)作为属性

swift - 使用通用关联类型扩展协议(protocol)