Вы можете сделать это, превратив каждый из ваших модулей в собственную реализацию черты, подобно тому, как gfx-rs
делает что-то.
Ваш "trait
" в действительности никогда не будет реализован с состоянием, а вместо этого будет набором связанных элементов, таких как функции, другие типы и т. Д.
Вы можете упаковать его как so :
#![allow(dead_code)]
mod foo {
pub fn print() { println!("hello from foo") }
}
mod bar {
pub fn print() { println!("hello from bar"); }
}
mod zam { // this may not exist depending on the platform, one will always exist
pub fn print() { println!("hello from zam"); }
}
struct FOO;
struct BAR;
struct ZAM;
trait RuntimeModule {
fn print();
}
impl RuntimeModule for FOO {
fn print() { foo::print(); }
}
impl RuntimeModule for BAR {
fn print() { bar::print(); }
}
impl RuntimeModule for ZAM {
fn print() { zam::print(); }
}
fn main() {
// Here we decide which to use
print_module::<FOO>();
}
// This is our "entrypoint"
fn print_module<T: RuntimeModule>() {
T::print();
}
Если мы решим, что использовать во время выполнения (в данном случае в main
), мы можем затем вызвать универсальную функцию, которая будет использовать связанные типы / функции дляпринимать решения.
Обратите внимание, что вы не сможете использовать Box<dyn RuntimeModule>
, если RuntimeModule
содержит связанные типы, которые различны для каждой реализации.