In rust, you can have a trait, implement it into a struct, and upcast your struct to a trait object :
trait T {}
struct S {}
impl T for S {}
fn main() {
let s: S = S {};
let s_as_t: &dyn T = &s;
}
This is an incredibly useful feature, because if I have multiple objects which all implement the trait T
, I can now put them all in a single array of type Vec<Box<dyn T>>
, and define global behaviors really easily by calling a function on each element.
BUT
How do I do the same thing when my original trait also has an associated type ?
This works really well, no pb :
trait T_Subtype {}
trait T {
type subtype: T_Subtype;
}
struct S {}
impl T_Subtype for S {}
impl T for S {
type subtype = S;
}
fn main() {
let s: S = S {};
let s_as_t: &dyn T<subtype = S> = &s;
}
But I can't find any way to upcast the associated type, the following code cannot compile :
trait T_Subtype {}
trait T {
type subtype: T_Subtype;
}
struct S {}
impl T_Subtype for S {}
impl T for S {
type subtype = S;
}
fn main() {
let s: S = S {};
let s_as_t: &dyn T<subtype = dyn T_Subtype> = &s; // only line that changes
}
Without this feature, I cannot put (this is an illustration) multiple structs S1
S2
and S3
, that all implement T
but might have a different subtype, in a single array, and I have to define global behaviors for each subtype, making it really hard to maintain (especially if there are multiple subtypes), even though the function I want to call on all of them is defined !