MST
星途 面试题库

面试题:Rust宏定义基础应用

请用Rust宏定义一个简单的日志记录宏,该宏接收一个字符串参数,在控制台输出当前时间(格式自定)加上传入的字符串信息。解释宏定义中的各个部分含义以及宏展开的过程。
46.9万 热度难度
编程语言Rust

知识考点

AI 面试

面试题答案

一键面试
// 定义日志记录宏
macro_rules! log_message {
    ($msg:expr) => {
        {
            use std::time::SystemTime;
            let now = SystemTime::now()
               .duration_since(SystemTime::UNIX_EPOCH)
               .expect("Time went backwards")
               .as_secs();
            println!("[{}] {}", now, $msg);
        }
    };
}

宏定义各部分含义

  1. macro_rules! log_message:定义一个名为log_message的宏。
  2. ($msg:expr):定义宏的参数,这里$msg是参数名,:expr表示该参数是一个表达式,意味着我们可以传入任何合法的Rust表达式,在本题中传入字符串。
  3. =>:分隔宏的模式匹配部分和替换部分。
  4. {}:替换部分的代码块。
  5. use std::time::SystemTime;:引入SystemTime模块用于获取当前时间。
  6. let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).expect("Time went backwards").as_secs();:获取当前时间距离Unix纪元的秒数。
  7. println!("[{}] {}", now, $msg);:格式化输出当前时间和传入的字符串信息。

宏展开过程

当代码中使用log_message!("Hello, world!");时,宏会进行如下展开:

  1. 模式匹配($msg:expr)"Hello, world!"匹配成功,$msg被替换为"Hello, world!"
  2. 替换部分的代码块被插入到调用宏的位置,即变为:
{
    use std::time::SystemTime;
    let now = SystemTime::now()
       .duration_since(SystemTime::UNIX_EPOCH)
       .expect("Time went backwards")
       .as_secs();
    println!("[{}] {}", now, "Hello, world!");
}

然后这段代码就像普通的Rust代码一样被编译和执行,在控制台输出当前时间加上传入的字符串信息。