繁体   English   中英

基于类型实现功能的宏

[英]Macro that implements functions based on type

如何编写一个为多个结构实现相同方法的宏? 这些方法应该根据结构略有不同。

代码应如下所示:

macro_rules! say_name {
    (for $($t:ty),+) => {
        $(impl $t {
            fn say_name(&self) {
                //if $t == A then self.say_a();
                //if $t == B then self.say_b();
            }
        })*
    };
}

struct A {

}

impl A {
    fn say_a(&self) {
        println!("A");
    }
}

struct B {

}

impl B {
    fn say_b(&self) {
        println!("B");
    }
}

say_name!(for A, B);

fn main() {
    let a = A {};
    let b = B {};
    a.say_name();
    b.say_name();
}

我的代码有点复杂,所以我提供了一个虚拟代码来解决这个问题。

您可以像这样将方法名称传递给宏

macro_rules! say_name {
    (for $($t:ty = ($f:ident) ),+) => {
        $(impl $t {
            fn say_name(&self) {
                <$t>::$f(self)
            }
        })*
    };
}

它现在被称为

say_name!(for A = (say_a), B = (say_b));

操场

您可以在宏定义可以使用的宏定义旁边定义一个特征,该特征“专门”用于 A 或 B:

pub mod private { // this mod has to be pub so the expanded code can use it
    pub trait SayNameImpl {
        fn say_name_impl(&self);
    }

    impl SayNameImpl for super::A {
        fn say_name_impl(&self) {
            self.say_a();
        }
    }

    impl SayNameImpl for super::B {
        fn say_name_impl(&self) {
            self.say_b();
        }
    }
}

macro_rules! say_name {
    (for $($t:ty),+) => {
        $(impl $t {
            fn say_name(&self) {
                use $crate::private::SayNameImpl;
                self.say_name_impl();
            }
        })*
    };
}

操场

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM