如何在宏中允许可选的尾随逗号? [英] How to allow optional trailing commas in macros?

查看:90
本文介绍了如何在宏中允许可选的尾随逗号?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我想要的综合示例:

Here's a synthetic example of what I want:

macro_rules! define_enum {
    ($Name:ident { $($Variant:ident),* }) => {
        pub enum $Name {
            None,
            $($Variant),*,
        }
    }
}

define_enum!(Foo { A, B });

该代码可以编译,但是如果添加逗号:

This code compiles, but if add a comma to it:

define_enum!(Foo { A, B, });
//                     ^

编译失败.我可以用以下方法解决它:

The compilation fails. I can fix it with:

($Name:ident { $($Variant:ident,)* })
//                             ^

但随后define_enum!(Foo { A, B });失败,

我应该如何编写宏来处理这两种情况:

How should I write a macro to handle both cases:

define_enum!(Foo { A, B });
define_enum!(Foo { A, B, });

推荐答案

处理这两种情况

您可以通过...处理这两种情况来处理这两种情况:

Handle both cases

You can handle both cases by... handling both cases:

macro_rules! define_enum {
    ($Name:ident { $($Variant:ident,)* }) => {
        pub enum $Name {
            None,
            $($Variant),*,
        }
    };
    ($Name:ident { $($Variant:ident),* }) => {
        define_enum!($Name { $($Variant,)* });
    };
}

define_enum!(Foo1 { A, B });
define_enum!(Foo2 { A, B, });

fn main() {}

我们已经将主要实现转移到了期望尾随逗号的版本.然后,我们添加了第二个子句,该子句与缺少逗号的情况匹配,并将其重写为带有逗号的版本.

We've moved the main implementation to the version that expects the trailing comma. We then added a second clause that matches the case with the missing comma and rewrites it to the version with a comma.

DK.指出了另一种选择,使尾部逗号本身是可选的:

DK. points out an alternative, making the trailing comma itself optional:

($Name:ident { $($Variant:ident),* $(,)* }) => { 
//                                 ^^^^^

这避免了将一个实现委派给另一个实现的需要.

This avoids the need to delegate from one implementation to the other.

在Rust 2018中,从Rust 1.32开始,您可以使用?宏转发器以更明显的方式编写此代码,并禁止多个尾随逗号:

In Rust 2018, starting with Rust 1.32, you can use the ? macro repeater to write this in a more obvious manner and disallow multiple trailing commas:

($Name:ident { $($Variant:ident),* $(,)? }) => { 
//                                 ^^^^^

这篇关于如何在宏中允许可选的尾随逗号?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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