在下面的代码中,实现中唯一不同的是println!
。
感觉应该有一种方法让我不必写出两个完全不同的实现,但是我还没找到方法。
pub trait ChangeDecision{
fn change_decision(&mut self);
}
impl ChangeDecision for Hero{
fn change_decision(&mut self){
self.should_change_decision = false;
let rand_num = rand::thread_rng().gen_range(1, 101) as f32 / 100.;
let mut prob_counter = 0.0;
for (action, prob) in &mut self.decisions.iter(){
prob_counter += *prob;
match prob_counter{
p if rand_num > p => {},
_ => {println!("{}: {:?}", self.name, action); self.current_decision = *action; break},
}
}
}
}
impl ChangeDecision for Team{
fn change_decision(&mut self){
self.should_change_decision = false;
let rand_num = rand::thread_rng().gen_range(1, 101) as f32 / 100.;
let mut prob_counter = 0.0;
for (action, prob) in &mut self.decisions.iter(){
prob_counter += *prob;
match prob_counter{
p if rand_num > p => {},
_ => {println!("{:?}: {:?}", self.side, action); self.current_decision = *action; break},
}
}
}
}
当实现完全相同时,我可以使用宏来实现两者。即。
macro_rules! impl_SimilarStuff {
($T:ident) => {
impl SimilarStuff for $T{
fn my_func(&mut self){
true
}
}
}
}
impl_SimilarStuff!(ThingOne);
impl_SimilarStuff!(ThingTwo);
但是我找不到任何'宏观条件'的例子
答案 0 :(得分:2)
我处理这个问题的方法是使用另一个特性来处理不同的部分。类似的东西:
trait PrintSomething {
fn print_something(&self, action: Action);
}
impl PrintSomething for Hero {
fn print_something(&self, action: Action) {
println!("{}: {:?}", self.name, action);
}
}
impl PrintSomething for Team {
fn print_something(&self, action: Action) {
println!("{}: {:?}", self.side, action);
}
}
// Now the macro would expand to:
impl ChangeDecision for Hero {
fn change_decision(&mut self){
self.should_change_decision = false;
let rand_num = rand::thread_rng().gen_range(1, 101) as f32 / 100.;
let mut prob_counter = 0.0;
for (action, prob) in &mut self.decisions.iter(){
prob_counter += *prob;
match prob_counter{
p if rand_num > p => {},
_ => {
self.print_something(action);
self.current_decision = *action;
break
},
}
}
}
}
答案 1 :(得分:1)
您可以将“条件”部分作为单独的参数传递给宏。沿着:
struct S1 {n1 : isize}
struct S2 {n2 : isize}
trait T {
fn print_me(self);
}
macro_rules! doit {
($t: ty, $member: ident) => (
impl T for $t {
fn print_me(self) {
println!("{}", self.$member);
}
}
)
}
doit!(S1, n1);
doit!(S2, n2);
fn main() {
let s1 = S1 {n1: 1};
let s2 = S2 {n2: 2};
s1.print_me();
s2.print_me();
}
如果“自定义部分”比某些简单语句大,您可以考虑将自定义部分提取为自己的特征,如@Chris Emerson所建议。
或者,您可以尝试编写一个泛型函数,将满足您特征的内容和自定义部分作为闭包。但是,这可能涉及修改您的特质。