![](/img/trans.png)
[英]Is it possible to tell if a field is a certain type or implements a certain method in a procedural macro?
[英]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.