实现嵌套特质

10

我有一些特征(在去除函数和一些参数膨胀后)看起来像:

trait Foo { }
trait Boo { }
trait Bar<T: Foo> { }
trait Baz { }

如果 U 实现了一些实现 FooT, 并且 U 还实现了 Boo, 那么就能够派生出一个 U 的实现,使其实现了 Baz. 然而,我并不能编写出使用 Rust 实现的有效代码。
几次尝试如下:
impl<T: Foo, U: Bar<T> + Boo> Baz for U { }

这段代码出现了错误:

错误:类型参数 T 没有被实现的特征、自身类型或谓词所约束 [E0207]

与此不同的是:

impl<U: Bar<T> + Boo> Baz for U { }

yields

错误:类型名 T 未定义或不在作用域内 [E0412]

有没有一种方法可以在(稳定版的)Rust中做到这一点?(希望没有任何动态分派)

编辑:有些人暗示了一些类似问题,对于这些问题本质上有两种方法(我认为这两个方法都不适合我的情况):

  1. 使用关联类型。我不想这样做,因为我想要跟踪 T,例如,我想编写一些函数,其签名类似于 fn bla<T: Foo, U: Bar<T>, V: Bar<T>>(),其中我想知道 UV 对于相同的 T 实现了 Bar<T>。(或者有没有一种使用关联类型来完成这个操作的方式?)
  2. 使用某种包装,将 UT 放入结构体中。我也不想使用这种方法,因为我有多个层次的“trait 依赖项”,所以在每个层次上包装会使代码膨胀很多。

因此,更新后的问题是:有没有一种解决这个问题的方法,而不使用关联类型或包装器?

1个回答

9

您可以通过将T作为关联类型来实现:

trait Foo { }
trait Boo { }
trait Bar {
    type T: Foo;
}
trait Baz { }

impl<U: Bar + Boo> Baz for U
    // this where clause is not necessary (this bound is already true)
    // where U::T: Foo
{ }

我不想这样做是因为我想跟踪 T,例如我想写一些函数,其签名如 fn bla<T: Foo, U: Bar<T>, V: Bar<T>>(),在这里我想知道 UV 实现了相同的 TBar<T>。 (或者有没有使用相关类型的方法?)

是的,您可以使用相关类型来实现:

fn bla<U: Bar, V: Bar<T = U::T>>() { }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接