刚开始学 rust 也想着像以前学其余语言一样找开源代码浏览来疾速体验一下,可是看了几个开源代码中夹杂着宏的利用齐全看不明确,特地是 bevy 中的 system,看 github 上有发问问这个的把源码还原到老版本才看进去的大略。
大略思路是先定义一个 trait
pub trait IntoSystem<Params>{fn system(&self);
}
而后给想要的类型实现这个 trait,实现的时候也能够应用泛型,上面是实现了一个没有参数的 trait
impl<TestType> IntoSystem<()> for TestType
where TestType:Fn()
{fn system(&self){self();
}
}
同样原理也能够实现 1 个参数的
impl<TestType> IntoSystem<u32> for TestType
where TestType:Fn(u32)
{fn system(&self){self(123);
}
}
这样本人定义的这两种类型的函数就能调用 system 了
fn fun_demo1(){println!("in fun_demo()!!");
}
fn fun_demo2(v :u32){println!("in fun_demo(u32)!!");
}
fun_demo1.system();
fun_demo2.system();
而 bevy 在老版本中看到一层宏定义的而后
impl_into_system!();
impl_into_system!(A);
impl_into_system!(A, B);
impl_into_system!(A, B, C);
impl_into_system!(A, B, C, D);
impl_into_system!(A, B, C, D, E);
impl_into_system!(A, B, C, D, E, F);
impl_into_system!(A, B, C, D, E, F, G);
impl_into_system!(A, B, C, D, E, F, G, H);
impl_into_system!(A, B, C, D, E, F, G, H, I);
impl_into_system!(A, B, C, D, E, F, G, H, I, J);
impl_into_system!(A, B, C, D, E, F, G, H, I, J, K);
impl_into_system!(A, B, C, D, E, F, G, H, I, J, K, L);
impl_into_system!(A, B, C, D, E, F, G, H, I, J, K, L, M);
impl_into_system!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
impl_into_system!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
impl_into_system!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
实现了最多 16 个参数的 trait 实现,在前面又用宏主动生成了这部分代码