簡體   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