One of the issues I'm running into is once I start using a trait object (&dyn Trait), every function below it must also use a trait object. This is leading to dynamic dispatch spreading through most of my codebase. I'm hoping to set up some boundaries where I pay the dynamic dispatch cost once and break out into static dispatch. I've figured out that I can use a method inside a trait to wrap a static dispatch function to accomplish this goal, but that is a bit verbose. Is there a more concise way I can accomplish this?
trait Animal {
fn wrapped_static_vocalize(&self);
}
#[derive(Debug)]
struct Cat;
impl Animal for Cat {
fn wrapped_static_vocalize(&self) {
println!("wrapped_static_vocalize");
static_vocalize(self);
}
}
fn dynamic_vocalize(animal: &dyn Animal) {
animal.wrapped_static_vocalize();
// How do I make the below line work?
static_vocalize(animal);
}
fn static_vocalize<A: std::fmt::Debug + Animal>(animal: &A) {
println!("static_vocalize {:?}", animal);
}
fn main() {
let c = Cat;
dynamic_vocalize(&c);
}