rust 特征的关联类型上的别名边界

8cdiaqws  于 2023-06-06  发布在  其他
关注(0)|答案(1)|浏览(171)

我正在尝试为一组具有关联类型的trait创建一个类型别名。然而,我的别名以相反的方式工作,也就是说,无论在哪里使用,它都需要满足边界。
类似于该情况的最小化示例如下。我想为trait Foo创建一个别名,只要它的类型A可以从u8创建:

trait Foo {
    type A;

    fn foo(&self, a: Self::A);
}

trait Alias: Foo
where
    <Self as Foo>::A: From<u8>,
{
}

impl<T> Alias for T
where
    T: Foo,
    <T as Foo>::A: From<u8>,
{
}

当我想在函数`test中使用这个别名时:

fn test<T: Alias>(x: &T, y: u8) {
    x.foo(y.into());
}

编译器会抱怨:

error[E0277]: the trait bound `<T as Foo>::A: From<u8>` is not satisfied
  --> src/lib.rs:20:12
   |
20 | fn test<T: Alias>(x: &T, y: u8) {
   |            ^^^^^ the trait `From<u8>` is not implemented for `<T as Foo>::A`
   |
note: required by a bound in `Alias`
  --> src/lib.rs:9:23
   |
7  | trait Alias: Foo
   |       ----- required by a bound in this trait
8  | where
9  |     <Self as Foo>::A: From<u8>,
   |                       ^^^^^^^^ required by this bound in `Alias`
help: consider further restricting the associated type
   |
20 | fn test<T: Alias>(x: &T, y: u8) where <T as Foo>::A: From<u8> {
   |                                 +++++++++++++++++++++++++++++

这意味着我还应该添加<T as Foo>::A: From<u8>约束,这是我想避免的。
我哪里做错了?如果这是编译器中的一个限制,有没有办法实现相同的行为?

s1ag04yj

s1ag04yj1#

如果你也在新的trait中创建了一个类型,这是可行的。

trait Alias: Foo {
    type AliasA: From<u8>;
}

impl<T> Alias for T
where
    T: Foo,
    <T as Foo>::A: From<u8>,
{
    type AliasA = T::A;
}

然后将T::A的任何用法替换为T::AliasA

相关问题