Hello everyone,
There are some aspects of trait definitions that I have a hard time to grasp, mainly the existence of both "regular" generics (the ones whose syntax is the same as for functions, structures and enums), associated types and the relationship between the two.
Let's start with the following code example (please tell me if there are any mistakes):
trait BinaryOperator<Rhs, Out> {
fn binary_operation(&self, rhs: &Rhs) -> Out;
}
impl<Ket, Complex> BinaryOperator<Ket, Complex> for Bra {
fn binary_operation(&self, rhs: &Ket) -> Complex {
// TODO
}
}
According to what I understood about associated types from the book, the following code example should be completely equivalent to the previous one (again correct me if you notice any mistakes):
trait BinaryOperator {
type Rhs;
type Out;
fn binary_operation(&self, rhs: &Self::Rhs) -> Self::Out;
}
impl BinaryOperator for Bra {
type Rhs = Ket;
type Out = Complex;
fn binary_operation(&self, rhs: &Ket) -> Complex {
// TODO
}
}
My questions are the following:
- Are the two examples above actually equivalent ? Or are there subtle difference in terms of functionality or whatever ?
- Can associated types replace "regular" generics in all cases ? Or are there some catch-22 type situations ? (Is this where GATs come into play ?)
- I know that the core and standard libraries use a combination of both (for example: the
Add
trait), so are "regular" generics and associated items actually complementary features ? If yes, then how so ?
Thank you in advance !
P.S. I have a hard time understanding what GATs bring to the table. Is it simply about being able to write something like:
trait BinaryOperator {
type Rhs;
type Out;
fn binary_operation(&self, rhs: &Self::Rhs) -> Self::Out;
}
impl<T> BinaryOperator for Bra {
type Rhs = Ket;
type Out = T;
fn binary_operation(&self, rhs: &Ket) -> T {
// TODO
}
}
Or is this already possible and GATs are about something more exotic ?