【问题标题】:How can I constrain generic type arguments of a trait which depend on each other?如何约束相互依赖的特征的泛型类型参数?
【发布时间】:2020-12-02 15:03:29
【问题描述】:

我对处理数据的类型有一个特征:

pub trait Stage<I, O>: Sized {}

这里,IO 分别代表输入和输出数据类型。我想创建一个Stage 的实现,它结合了另外两个Stages:

pub struct CompoundStage<S0: Stage<_, _>, S1: Stage<_, _>>(S0, S1);

CompoundStage 本身必须是Stage

impl<S0: Stage<_, _>, S1: Stage<_, _>> Stage<S0::I, S1::O> for CompoundStage<S0, S1> {}

如何约束CompoundStage 的类型参数,以使“中间”类型保持一致(即S0::O == S1::I)?我知道我可以通过添加另一个类型参数来做到这一点,如下所示,但有没有更简洁的方法?

pub struct CompoundStage<S0: Stage<_, T>, S1: Stage<T, _>, T>(S0, S1);

impl<S0: Stage<_, T>, S1: Stage<T, _>, T> Stage<S0::I, S1::O> for CompoundStage<S0, S1, T> {}

【问题讨论】:

  • 很难回答您的问题,因为它不包含minimal reproducible example。您提供的代码与自身不一致,无法编译。如果您尝试在 Rust Playground 上重现您的错误,如果可能的话,这将使我们更容易为您提供帮助,否则在全新的 Cargo 项目中,然后在 edit 您的问题中包含附加信息。您可以使用Rust-specific MRE tips 来减少您在此处发布的原始代码。谢谢!

标签: generics rust type-constraints


【解决方案1】:

可能想要一个具有关联类型而不是泛型类型的特征:

pub trait Stage: Sized {
    type I;
    type O;
}

pub struct CompoundStage<S0, S1>(S0, S1);

impl<S0, S1> Stage for CompoundStage<S0, S1>
where
    S0: Stage,
    S1: Stage<I = S0::O>,
{
    type I = S0::I;
    type O = S1::O;
}

另见:


如果必须使用泛型类型,则需要引入PhantomData

use std::marker::PhantomData;

pub trait Stage<I, O>: Sized {}

pub struct CompoundStage<S0, S1, M>(S0, S1, PhantomData<M>);

impl<S0, S1, I, O, M> Stage<I, O> for CompoundStage<S0, S1, M>
where
    S0: Stage<I, M>,
    S1: Stage<M, O>,
{
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多