Hello.
The question I have has partially been answered here
Here is an example I am playing with
pub trait X {
fn x(&self) -> u64;
}
pub struct Y {}
impl X for Y {
fn x(&self) -> u64 {
return 1;
}
}
pub struct Z {}
impl X for Z {
fn x(&self) -> u64 {
return 2;
}
}
#[inline(never)]
pub fn generic_call_x<T: X + ?Sized>(x: &T) {
println!("{}", x.x());
}
#[inline(never)]
pub fn dynamic_call_x(x: &dyn X) {
println!("{}", x.x());
}
pub fn main() {
let y = Y {};
let z = Z {};
generic_call_x(&y);
generic_call_x(&z);
dynamic_call_x(&y);
dynamic_call_x(&z);
let vec_of_x: Vec<Box<dyn X>> = vec![Box::new(Y {}), Box::new(Z {})];
dynamic_call_x(vec_of_x[0].as_ref());
dynamic_call_x(vec_of_x[1].as_ref());
generic_call_x(vec_of_x[0].as_ref());
generic_call_x(vec_of_x[1].as_ref());
}
I can achieve the same result with both dynamic_call_x and generic_call_x. godbolt explorer shows three instances of generic_call_x and one instance of dynamic_call_x. Most of the examples on dynamic dispatch in Rust use dyn Trait syntax. I can see it is more explicit, but are there other advantages in using dyn Trait syntax over generic variation, which also allows for static dispatch. What are scenarios when one if preferable over the other ?
I think the main reason to use &dyn Trait instead of generics is when you have a reason to avoid monomorphization -- you want shorter compile times and less generated code. That includes situations where you want to minimize binary size, e.g. some embedded scenarios. Conventional wisdom is that the code will be slower as it's harder to optimize through virtual calls, and you lose the ability for concrete-type-specific optimizations in each monomorphized version. (Depending on the situation though, you may end up with better instruction cache utilization if you have less code paths -- always measure.)
There are also plenty of situations where using dyn Trait instead of generics just isn't an option or is significantly less ergonomic, e.g.:
Thank you @quinedot.
I understood that generics is more flexible, and generally more performant, but in certain situations dynamic version may be preferable.