I am trying to better understand Rust Generic Associate Type by comparing Rust Traits to C# interfaces.
In Rust we can define Iterator trait with GATs such as
trait iterator { type Output; fn next(&mut self) -> Option<Self::Item>; ... } Which I believe is similar to C# interface where the associated type is defined via the out paramter
public interface IEnumerable<out T> : IEnumerable { IEnumerator<T> GetEnumerator(); } Q1 - are the two definitions comparable?
Q2 - what is the difference between Rust Iterator defined above with GAT vs compared to below?
trait NewIterate<T> { fn next(&mut self) -> Option<T>; } Q3 In C# I can define a self referencing interface like so
interface IMultiply<O, R>{ R multiply(IMultiply<O,R> rhs); } How do i do the same in Rust with traits? I tried below but both returned "cannot find MyMultiply in scope"
trait MyMuliply<T, O>{ fn mul(&self, rhs: impl MyMultiply) -> O; } trait MyMuliply<T, O>{ fn mul(&self, rhs: MyMultiply) -> O; } Q4 Taking Example from Orielly's Programming in Rust book, we cannot do below in Rust because the Size of both Circle and Triangle are different
trait Shape{ fn new() -> Self; fn area(&self) -> f64; } /* we cannot do like this */ fn make_shape(shape: &str) -> impl Shape{ match shape{ "circle" => Circle::new(), "triangle" => Triangle::new() // error: incompatible types } } Yet in C# i can do something like below
public interface IShape{ public IShape Construct(); public Double Area(); } public class Circle:IShape{ public IShape Construct(){ return new Circle(); } public Double Area(){ return 100; } } public class Triangle:IShape{ public IShape Construct(){ return new Triangle(); } public Double Area(){ return 50; } } public class Program { IShape MakeShape(String str){ if(str.Equals("circle")){ return new Circle(); } return new Triangle(); } } I am pretty sure I am missing very basic here as i would think Rust would be better at type system, please if someone can correct me?
Edit - What helped me was this answer Why don't associated types for protocols use generic type syntax in Swift?. Guess i was asking for difference between Associated Type vs Generic, the difference is that with generic types Callee drives the type info, while with assoicated type it is the type (Napier's example of Array is what helped me clarify it for me)
type Outputis just an "associated type". "Generic associated types" refer to a specific, currently unstable feature where associated types can take generic type or lifetime parameters, e.g.type Output<T>.