I recently ran into a trait syntax that I don't think I have seen before:
trait T: E {
// ....
}
where E
is some other trait. What is the semantics of this syntax?
I recently ran into a trait syntax that I don't think I have seen before:
trait T: E {
// ....
}
where E
is some other trait. What is the semantics of this syntax?
It means that every type which implements trait T
must also implement trait E
. In practical terms, it means that if you have a generic function fn example<A:T>(a:A) { ... }
, then you are allowed to call methods defined by either T
or E
on the value a
.
It means E
is a Supertrait of T
(similar to superclasses in object oriented languages, except we're having traits here, and not classes, so there are differences, of course).
Thank both of y'all for y'all's reply!
It's short syntax for trait T where Self: E {}
which means if some type implements T
, it also must implement E
.
It does not add a subclassing relationship (at least not yet), so types like &dyn T
remain incompatible with &dyn E
.
Note that while this is technically true, supertrait bounds (i.e. bounds on Self
) on a trait behave differently from e.g. bounds on parameters. When you have
trait Foo<T> where T: Bar { /* methods... */ }
then every time you use S: Foo<T>
, you will need to put extra T: Bar
bounds. OTOH,
trait Baz: Qux { /* methods... */ }
or
trait Baz where Self: Qux { /* methods... */ }
has the effect that when you use S: Baz
, the S: Qux
will be implied, and does not need to be written explicitly. E.g.
// doesn't work
fn f<S, T>()
where
S: Foo<T>,
{}
// works
fn g<S, T>()
where
S: Foo<T>,
T: Bar,
{}
vs.
// works
fn h1<S>()
where
S: Baz,
{}
// works, and equivalent to h1
fn h2<S>()
where
S: Baz,
S: Qux,
{}
That'd require #![feature(trait_upcasting)]
, I assume?
Yes
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.