如何避免传递类型依赖?

How to avoid transitive type dependencies?

我想了解更多有关使用类型参数和特征构建软件的信息。我可以让我的程序工作,我只是想改善解耦。

当我依赖于具有类型参数的类型时,比如 A<T>,其中类型参数具有约束,这意味着我也必须依赖于约束。例如,

fn x<T: C>(arg: A<T>)

没有指定 C 编译器会抱怨特征绑定 A: C 不是 使满意。对我来说这没有意义。我不需要 C 方法。 A C 可能会发生变化,这不会影响我。

如何避免依赖 C

这是我用来探索可能的解决方案的 larger playground example 的相关部分。完全做作,我的真实代码有四个具有不同约束的类型参数。

mod auth {
    pub trait Authz {
        fn allowed(&self) -> bool;
    }
}

mod limiter {
    use super::auth;

    pub struct Limiter<T: auth::Authz> {
        pub m: T,
        pub data: i32,
    }

    impl<T: auth::Authz> Limiter<T> {
        pub fn limit(&self) {
            if ! self.m.allowed() { panic!("not allowed"); }
        }
    }
}

// Works but is depedendent on Authz for every method. How do I avoid naming Authz within service?!
mod service {
    use super::limiter;

    pub struct Service;

    impl Service {
        pub fn invoke<T: super::auth::Authz>(a: limiter::Limiter<T>) {
            a.limit()
        }
    }
}

playground

我为理解所做的努力

您并不是唯一一个认为应该可以省略此处隐含特征约束的人。 an accepted RFC about implied trait bounds 允许您在实施后忽略示例中的特征界限。

隐含特征边界已经在 the experimental constraint solver "chalk", which is intended to be eventually integrated in the Rust compiler. According to the tracking issue for the mentioned RFC 中实现,我们将不得不等待它发生,然后我们才能在 Rust 中看到对隐含特征边界的支持。