I have a trait that encapsulate a behavior, through associated functions.
pub trait Interface {
fn bar(...);
}
struct BehaviorA;
impl Interface for BehaviorA { ... }
struct BehaviorB;
impl Interface for BehaviorB { ... }
I am implementing foo()
, that receive the Interface
as a compile time dependency injection to be able to specialize it's behavior.
What syntax should I prefer?
fn foo<T: Interface>(...) {
T::bar(...)
}
// Now we can select at compile time witch behavior to use for foo()
fn main() {
foo::<BehaviorA>(...); // called using turbofish
}
or
fn foo<T: Interface>(_:T, ...) {
T::bar(...);
}
fn main() {
foo(T, ...); // called by creating an instance of the zero-sized struct
}
To give an example of use of this pattern, Interface
could be TextFormatter
, which has associated functions like bold()
and strike()
. Then you have a MarkdownFormatter
, HtmlFormatter
and a AnsiFormatter
that implements TextFormatter
. Finally foo()
just need a TextFormatter
, and will delegate the formatting to it.