iT邦幫忙

2023 iThome 鐵人賽

DAY 12
0

接下來我們要來介紹 Macro 了!

Macro 是什麼

Macro 主要是用一小段程式碼來寫另一段的程式碼,這個概念跟 Meta Programming 很像,主要是避免寫過多重複的程式碼

這聽起來跟 Function 蠻像的,不過 Macro 有 Function 沒有的特性,能應用的範圍更廣,我們今天也會一併介紹!

Meta Programming

剛剛提到 Macro 的概念跟 Meta Programming 很像,那 Meta Programming 又是什麼?

Meta Programming 主旨是在減少重複性高且繁瑣的程式碼,以更讓電腦看得懂的前提出發,將程式碼寫的更精簡,且更好維護

不過缺點在於,無法兼具易讀性,當我們寫出來的程式碼越精簡,有可能對於開發者來說會越難懂

Macro 與 Function 不同之處在哪

這樣看起來 Macro 跟 Function 好像蠻像的,兩個都是將重複的事情整理起來,
不過 Macro 能做到的事情比 Function 更多,不僅可以傳遞多個參數,參數的型別也不會被限制
Macro 在編譯前就會先展開到執行緒中,而 Function 則是走一般的編譯流程並且執行

Macro 的應用方式

我們可以來客製化 Macro ,將重複性高的程式碼變成一個巨集,並重複使用它

macro_rulse!

macro_rules! 可以用來自定義的 macro

() 裡面可以放參數,稍後會有範例

{} 裡面的程式碼會在編譯前擴展到呼叫的 block 中

fn main() {
    macro_rules! introduction {
        () => {
            println!("My name is Ning!")
        };
    }

    introduction!()
}
> cargo run

My name is Ning!

如果我們要帶參數的話

$message $ 是 macro 的參數符號
expr 指的是目前參數是什麼
:為標示符號,表示我目前這個參數是什麼

除了 expr 還有其他類型等等

stmt 一個句子,例如 let x = 5;
pat 一個模式,matchif let 就可以用模式
expr 一個表達式,會返回值的,像是函式、運算式
ty 一種類型,像是 i32&str

fn main() {
    macro_rules! introduction {
        ($message:expr) => {
            println!("My name is {}!", $message)
        };
    }

    introduction!("Ning")
}

macro 放置到 main 中,在編譯前會展開,並且將參數帶入,會做出 println!("My name is {}!", "Ning") 的程式碼

> cargo run

My name is Ning!

如果我們需要依據不同的參數執行多次的話

macro 可以傳遞多個參數,並且執行多次

要讓他重複執行的話,我們需要使用 $(...)* 符號,而 ... 可以是一個 expr 或是一個 pat,或其他標示符號也可以

我們可以看到下方的 () 第二個參數為 * 這表示他會重複 $() 裡面的參數

fn main() {
    macro_rules! introduction {
        ($($message:expr), *) => {
            $(
                println!("My name is {}!", $message);
            )*
        };
    }

    introduction!("Ning", "Jane", "Amy");
}

當我們編譯完並執行時,傳了三次參數進去,他就會跑三次結果出來

> cargo run

My name is Ning!
My name is Jane!
My name is Amy!

上一篇
Day 11 unwrap 跟 expect
下一篇
Day 13 Match
系列文
成為程式界的 F1 賽車手,用 30 天認識 Rust 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言