You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Rust固定参数log宏改写为支持任意入参的可变参数宏

Rust 实现支持任意数量入参的log!声明宏

现有实现

你当前编写的log!宏仅支持0-3个入参,逻辑是将所有传入参数按顺序拼接为字符串后调用info!输出日志,代码如下:

//Amazing log function that can take up to three parameters!!!
macro_rules! log {
        // todo variadic
        () => {
            let string = " ";
            info!(" ");
        };
        ($a:expr) => {
            let string = format!("{}", format_args!("{}", $a));
            info!("{}", string);
        };
        ($a:expr,$b:expr) => {
            let string = format!("{}", format_args!("{}{}", $a, $b));
            info!("{}", string);
        };
        ($a:expr,$b:expr,$c:expr) => {
            let string = format!("{}", format_args!("{}{}{}", $a, $b, $c));
            info!("{}", string);
        };
    }

调用示例:

let number = 163.19;
log!("Heeey fam is this number right: ", number, ". No, it's wrong");
// 输出: [TIME INFO project] Heeey fam is this number right: 163.19. No, it's wrong

可变参数实现方案

Rust 声明宏macro_rules!原生支持可变参数匹配,不需要为每个参数数量单独编写分支,使用$(...),*/$(...),+的重复匹配模式即可支持任意数量的入参。

与原逻辑完全一致的实现

以下实现完全保留你原来「所有参数直接按Display规则拼接输出」的逻辑,同时支持任意数量参数,还去掉了原代码里多余的中间字符串分配,性能更好:

macro_rules! log {
    // 0个参数的分支,和原有逻辑保持一致
    () => {
        info!(" ");
    };
    // 匹配1个及以上逗号分隔的表达式,末尾$(,)?支持最后一个参数后加逗号的Rust常规写法
    ($($arg:expr),+ $(,)?) => {
        // 编译期自动生成和参数数量一致的"{}{}...{}"格式串,直接传给info!,无额外运行时开销
        info!(concat!($("{}"),+), $($arg),+);
    };
}

规则说明

  • $($arg:expr),+ $(,)? 是声明宏的重复匹配语法:
    • $arg:expr 表示匹配单个表达式类型的参数,绑定到$arg变量
    • 括号后的,表示参数之间用逗号分隔
    • 末尾的+表示该模式匹配至少1次,对应1到任意多个参数;如果需要匹配0次及以上可以替换为*
    • 最后的$(,)?表示允许参数列表末尾加可选的逗号,符合Rust日常编码习惯
  • 展开时concat!($("{}"),+)会在编译期拼接出和参数数量匹配的格式化字符串(比如3个参数就会生成"{}{}{}"),之后$($arg),+把所有捕获的参数按原顺序展开传入,和你手动写固定数量参数分支的行为完全一致。

扩展:对齐标准info!的格式化用法

如果你不需要强制把所有参数直接拼接,想让宏支持和标准库日志宏一样的格式化占位符写法,可以直接用透传版本,实现更简洁:

macro_rules! log {
    // 透传所有输入参数给info!,支持所有标准格式化语法
    ($($arg:tt)*) => {
        info!($($arg)*);
    };
}

这个版本既支持你原来的多参数用法,也支持log!("数值: {}, 字符串: {}", 123, "test")这类带占位符的调用,和tracing/log crate的info!宏行为完全对齐。


内容的提问来源于stack exchange,提问作者Bron

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 07:51:26