为什么我不能在带有类型参数的特征上添加一揽子暗示? [英] Why can't I add a blanket impl on a trait with a type parameter?

查看:44
本文介绍了为什么我不能在带有类型参数的特征上添加一揽子暗示?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下两个特征:

pub trait Foo {
    fn new(arg: u32) -> Self;
}

pub trait Bar<P>: Foo {
    fn with_parameter(arg: u32, parameter: P) -> Self;
}

我想添加一揽子提示:

impl<T: Bar<P>, P: Default> Foo for T {
    fn new(arg: u32) -> Self {
        Self::with_parameter(arg, P::default())
    }
}

但是我得到了编译器错误:

But I get the compiler error:

error[E0207]: the type parameter `P` is not constrained by the impl trait, self type, or predicates
 --> src/lib.rs:9:17
  |
9 | impl<T: Bar<P>, P: Default> Foo for T {
  |                 ^ unconstrained type parameter

我认为我收到此错误是因为我违反了特质一致性规则,但是我不确切知道这会破坏什么规则.为什么不允许这种模式?而且,更重要的是,我可以在不出错的情况下实现我想要的东西吗?

I think I get this error because I'm violating trait coherence rules, but I don't understand exactly what rule this would break. Why is this pattern not allowed? And, more importantly, can I achieve what I want without getting an error?

推荐答案

问题是单个类型可以为P的多个值实现Bar<P>.如果您有一个实现了Bar<i32>Bar<String>的结构Baz,那么Foo::new应该为P使用哪种类型?

The problem is that a single type could implement Bar<P> for multiple values of P. If you had a struct Baz that implemented Bar<i32> and Bar<String>, which type should Foo::new use for P?

唯一的解决方案是确保单个类型不能多次实现Bar(如果这不是您想要的,那么您的设计就有缺陷!).为此,我们必须用关联的类型替换P类型参数.

The only solution is to ensure that a single type cannot implement Bar more than once (if that's not what you want, then you have a flaw in your design!). To do so, we must replace the P type parameter with an associated type.

pub trait Bar: Foo {
    type Parameter;

    fn with_parameter(arg: u32, parameter: Self::Parameter) -> Self;
}

impl<T> Foo for T
where
    T: Bar,
    T::Parameter: Default,
{
    fn new(arg: u32) -> Self {
        Self::with_parameter(arg, T::Parameter::default())
    }
}

Bar的实现如下所示:

struct Baz;

impl Bar for Baz {
    type Parameter = i32;

    fn with_parameter(arg: u32, parameter: Self::Parameter) -> Self {
        unimplemented!()
    }
}

另请参阅:

这篇关于为什么我不能在带有类型参数的特征上添加一揽子暗示?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆