generics - 为什么我不能在带有类型参数的特征上添加一揽子实现?

标签 generics rust traits type-parameter

考虑这两个特征:

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())
    }
}

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

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

我认为我收到此错误是因为我违反了特征一致性规则,但我不明白这会违反什么规则。为什么不允许这种模式?而且,更重要的是,我能否在不出错的情况下实现我想要的目标?

最佳答案

问题是单个类型可以实现 Bar<P>对于 P 的多个值.如果你有一个结构 Baz实现 Bar<i32>Bar<String> , 哪种类型应该 Foo::new用于 P

唯一的解决办法是确保单一类型无法实现Bar不止一次(如果这不是您想要的,那么您的设计就有缺陷!)。为此,我们必须替换 P具有关联类型的类型参数。

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!()
    }
}

另见:

关于generics - 为什么我不能在带有类型参数的特征上添加一揽子实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42613974/

相关文章:

scala - 在 scala 中基于鸭子类型定义泛型类型?

java - 反序列化集合时不安全的泛型转换

java - 在java中填充通用数组

Rust 错误处理——捕获多个错误

str 和 String 的 Rust 生命周期

struct - 可以在 Rust 中对同构结构/元组的所有成员进行操作吗?

rust - 如何向现有原始类型添​​加构造函数?

java - 以不同 ArrayList 类型作为参数的构造函数

Scala:抽象类构造函数参数与 Trait val 成员?

generics - 我可以在 Rust 中使这个断言通用吗?