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

如何为Rust声明式宏的默认参数设置‘私有’属性

实现Rust声明式log!宏,默认隐藏未标记public!的参数

要实现你需要的效果,不用复杂的函数式宏,通过声明式宏的模式匹配就能搞定核心逻辑:让log!宏自动把所有未用public!包裹的参数替换为<private>,private!包裹的参数也统一处理为<private>。

完整实现代码

macro_rules! log {
    // 匹配格式字符串 + 逗号分隔的参数列表(支持末尾可选逗号)
    ($fmt:expr, $($args:tt),* $(,)?) => {
        let log_str = format!($fmt, $(process_arg!($args)),*);
        println!("{}", log_str);
    };
}

// 辅助宏:处理单个参数,判断是否为public!标记
macro_rules! process_arg {
    // 匹配public!(x)的形式,返回原始值
    (public!($arg:tt)) => {
        $arg
    };
    // 匹配所有其他情况(包括private!(x)或普通值),返回<private>
    ($_arg:tt) => {
        "<private>"
    };
}

// 保留原有的private!宏(可选,因为process_arg会自动处理它)
macro_rules! private {
    ($arg:tt) => {
        "<private>"
    };
}

fn main() {
    log!("{} {} {}", private!(1), public!(2), 3);
    // 输出:<private> 2 <private>
}

核心逻辑说明

  1. log!宏的参数分解:
    宏首先匹配格式字符串$fmt:expr,以及后续逗号分隔的所有参数$($args:tt),*,$(,)?是为了兼容参数列表末尾加逗号的写法(Rust常用语法糖)。

  2. 辅助宏process_arg!的分支匹配:

    • 第一个分支专门捕获public!($arg)的调用,直接返回内部的原始参数值;
    • 第二个分支匹配所有其他情况:不管是private!($arg)还是普通的字面量/变量,都统一替换为<private>字符串。
  3. 原问题的解决点:
    你之前的代码直接把参数传给format!,导致未标记的参数(比如示例中的3)直接输出原值。现在通过process_arg!对每个参数提前处理,就能实现“默认私有,仅public!标记的参数可见”的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:15:44