Can a trait have a supertrait that is parameterized by a generic?

倖福魔咒の 提交于 2020-12-26 08:32:28

问题


Can you do something like this in Rust?

trait A : forall<T> B<T> { ... }

That is, if we want:

impl A for D { ... }

We must first implement:

impl<T> B<T> for D { ... }

回答1:


No. Rust's type system doesn't currently support any features involving higher kinded types. It does, however, support a similar construction to what you described, but limited to lifetime parameters. For example:

trait B<'a> {}

trait A: for<'a> B<'a> {}

struct D;

impl A for D { }

This is an error:

error[E0277]: the trait bound `for<'a> D: B<'a>` is not satisfied
 --> src/lib.rs:7:6
  |
7 | impl A for D { }
  |      ^ the trait `for<'a> B<'a>` is not implemented for `D`

Until you add the blanket implementation:

impl<'a> B<'a> for D { }

It's not impossible that Rust will eventually add similar functionality for types too, but I wouldn't expect it any time soon.




回答2:


While the language is unable to specify such a higher kinded constraint, it is often possible to rethink the trait B so that its implementation is universal over this parameter type T.

Considering this example of B:

trait B<T> {
    fn foo(bar: T) -> u32;
}

A type that implements B for any T would be practically equivalent to the type implementing the trait below:

trait UniversalB {
    fn foo<T>(bar: T) -> u32;
}

This one declares the type parameters at method call level. While this trait is no longer object safe, it can still be used as a supertrait:

trait A: UniversalB {}

The implementations may need to be adjusted accordingly.

See also:

  • The Rust Programming Language, Chapter 10, Section 1 on Generic Data Types In Method Definitions


来源:https://stackoverflow.com/questions/56329170/can-a-trait-have-a-supertrait-that-is-parameterized-by-a-generic

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!