使用分隔符对 Rust 宏中的变量参数进行字符串化

问题描述 投票:0回答:1

鉴于 Rust 宏中的参数数量可变(即

$($varargs:pat),*
),我想将它们很好地分隔开来打印。

例如,给定一个宏

something!
,它采用可变数量的参数,例如
something!(a, b, c)
,我想将它们打印成字符串:
"a, b, c"

我在网上找不到任何相关资源,因此将其发布到世界上,以防对其他人有所帮助。其他答案表示赞赏。

rust macros rust-macros
1个回答
0
投票

加入向量解决方案

macro_rules! something {
    ($($varargs:pat),* $(,)?) => {
        println!("{}", something!(@stringify_varargs $($varargs),*));
    };

    (@stringify_varargs $($varargs:pat),*) => {
        {
            vec![$(format!("{}", stringify!($varargs))),*].join(", ")
        }
    };
}

fn main() {
    let a = 1;
    let b = 2;
    let c = 3;
    something!(a, b, c);
}

改变字符串解决方案

macro_rules! something {
    ($($varargs:pat),* $(,)?) => {
        println!("{}", something!(@stringify_varargs $($varargs),*));
    };

    (@stringify_varargs $($varargs:pat),*) => {
        {
            let mut patterns = String::new();
            $(
                patterns.push_str(&format!("{}, ", stringify!($varargs)));
            )*

            // Remove the trailing comma
            let _ = patterns.truncate(patterns.len() - 2);
            patterns
        }
    };
}

fn main() {
    let a = 1;
    let b = 2;
    let c = 3;
    something!(a, b, c);
}

递归解法

macro_rules! something {
    ($($varargs:pat),* $(,)?) => {
        println!("{}", something!(@stringify_varargs $($varargs),*));
    };

    (@stringify_varargs $($expected:pat),*) => {
        something!(@stringify_varargs_helper $($expected),*)
    };
    (@stringify_varargs_helper $first:pat, $($rest:pat),*) => {
        concat!(stringify!($first), $(", ", stringify!($rest)),*)
    };
    (@stringify_varargs_helper $last:pat) => {
        // Do not print last comma
        stringify!($last)
    };
}

fn main() {
    let a = 1;
    let b = 2;
    let c = 3;
    something!(a, b, c);
}

© www.soinside.com 2019 - 2024. All rights reserved.