# 常量宏

C 中常量宏的四种使用方式:

#define MAX_SIZE 1024
#define MY_STR "root/api/"
#define MYTY int
#define MYNIL

以下是对应的 Rust 版本的处理方案:

macro_rules! my_def {
    ($name: ident : $ty: ty, $value: expr) => {
        #[allow(non_upper_case_globals)]
        pub const $name: $ty = $value;
    };
    ($name: ident, $ty: ty) => {
        #[allow(non_camel_case_types)]
        pub type $name = *mut $ty;
    };
}
my_def!(MAX_SIZE: i32, 1024);
my_def!(MY_STR: &'static str, "root/api/");
my_def!(MYTY, i32);
my_def!(MYNIL: bool, true);
fn main() {
    let num = MAX_SIZE;
    println!("MAX_SIZE = {}", num);
    let mystr = MY_STR;
    let user = MY_STR.to_owned() + "jiale/";
    println!("MY_STR = {}, user = {}", mystr, user);
    let jude = MYNIL;
    if jude == true {
        println!("This is MYNIL.");
    }
    let mut x: i32 = 42;
    let p: MYTY = &mut x;
    unsafe {
        *p = 123;
        println!("x = {}", x); // 输出 x = 123
    }
}
/*
输出:
MAX_SIZE = 1024
MY_STR = root/api/, user = root/api/jiale/
This is MYNIL.
x = 123
*/

# 语句宏和函数宏

macro_rules! function_macro {
    (
        $(#[$attr:meta])*
        $vis:vis fn $name:ident ( $( $arg:ident : $t:ty ),* ) -> $ret:ty {
            $($body:tt)*
        }
    ) => {
        $(#[$attr])*
        $vis fn $name ( $( $arg : $t ),* ) -> $ret {
            $($body)*
        }
    };
}
function_macro!(
    pub fn add(a: i32, b: i32) -> i32 {
        a + b
    }
);
function_macro!(
    pub fn myprint(a: i32, b: i32) -> i32 {
        println!("{}", a*b);
        a*b
    }
);
function_macro!(
    pub fn mymax(a: i32, b: i32) -> i32 {
        if a > b {
            a
        } else {
            b
        }
    }
);
function_macro!(
    pub fn mytotal(a: i32, b: i32) -> i32 {
        let mut sum = 0;
        for i in a..=b {
            sum += i;
        }
        sum
    }
);
function_macro! {
    pub fn factorial(n: u64) -> u64 {
        if n <= 1 {
            1
        } else {
            n * factorial(n - 1)
        }
    }
}
fn main() {
    let a = 1;
    let b = 2;
    let c = add(a, b);
    println!("{}", c);
    let d = myprint(a,b);
    println!("a * b = {}", d);
    let maxnum = mymax(1,2);
    println!("maxnum = {}", maxnum);
    let total = mytotal(1,10);
    println!("total = {}", total);
    let result = factorial(5);
    println!("5! = {}", result); 
}
/*
输出:
3
2
a * b = 2
maxnum = 2
total = 55
5! = 120
*/