如何在Rust中编写宏以匹配集合中的任何元素? [英] How to write a macro in Rust to match any element in a set?

查看:126
本文介绍了如何在Rust中编写宏以匹配集合中的任何元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C语言中,我习惯于:

In C, I'm used to having:

if (ELEM(value, a, b, c)) { ... }

这是一个具有可变数量参数以避免输入的宏

which is a macro with a variable number of arguments to avoid typing out

if (value == a || value == b || value == c) { ... }

AC示例可以在 Varargs`ELEM`宏中与C一起使用.

在Rust中有可能吗?我认为它将使用match.如果是这样,如何使用可变参数来实现这一目标?

Is this possible in Rust? I assume it would use match. If so, how would variadic arguments be used to achieve this?

推荐答案

macro_rules! cmp {
    // Hack for Rust v1.11 and prior.
    (@as_expr $e:expr) => { $e };

    ($lhs:expr, $cmp:tt any $($rhss:expr),*) => {
        // We do this to bind `$lhs` to a name so we don't evaluate it multiple
        // times.  Use a leading underscore to avoid an unused variable warning
        // in the degenerate case of no `rhs`s.
        match $lhs { _lhs => {
            false || $(
                cmp!(@as_expr _lhs $cmp $rhss)
            ) || *
        //    ^- this is used as a *separator* between terms
        }}
    };

    // Same, but for "all".
    ($lhs:expr, $cmp:tt all $($rhss:expr),*) => {
        match $lhs { _lhs => {
            true && $( cmp!(@as_expr _lhs $cmp $rhss) ) && *
        }}
    };
}

fn main() {
    let value = 2;
    if cmp!(value, == any 1, 2, 3) {
        println!("true! value: {:?}", value);
    }
    if cmp!(value*2, != all 5, 7, 1<<7 - 1) {
        println!("true! value: {:?}", value);
    }
}

这篇关于如何在Rust中编写宏以匹配集合中的任何元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆