首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >@符号在锈蚀声明宏中意味着什么?

@符号在锈蚀声明宏中意味着什么?
EN

Stack Overflow用户
提问于 2019-01-28 16:31:50
回答 1查看 2.1K关注 0票数 12

我见过宏中使用的@符号,但在锈蚀书或任何官方文档或博客文章中都没有提到它。例如,在这个堆栈溢出回答中,它的用法如下:

代码语言:javascript
复制
macro_rules! instructions {
    (enum $ename:ident {
        $($vname:ident ( $($vty: ty),* )),*
    }) => {
        enum $ename {
            $($vname ( $($vty),* )),*
        }

        impl $ename {
            fn len(&self) -> usize {
                match self {
                    $($ename::$vname(..) => instructions!(@count ($($vty),*))),*
                }
            }
        }
    };

    (@count ()) => (0);
    (@count ($a:ty)) => (1);
    (@count ($a:ty, $b:ty)) => (2);
    (@count ($a:ty, $b:ty, $c:ty)) => (3);
}

instructions! {
    enum Instruction {
        None(),
        One(u8),
        Two(u8, u8),
        Three(u8, u8, u8)
    }
}

fn main() {
    println!("{}", Instruction::None().len());
    println!("{}", Instruction::One(1).len());
    println!("{}", Instruction::Two(1, 2).len());
    println!("{}", Instruction::Three(1, 2, 3).len());
}

从用法上看,它似乎用于声明另一个宏,该宏是主宏的本地宏。

这个符号意味着什么?你为什么要使用它而不是仅仅创建另一个顶级宏?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-28 16:47:46

在宏的模式匹配部分,符号可以表示作者希望它们表示的任何意思。前导符号@通常用于表示宏的“实现细节”--这是外部用户不希望使用的宏的一部分。

在本例中,我使用它来模式匹配元组参数以获得元组参数的计数。

在宏之外,@符号用于匹配模式,同时还为整个模式指定名称:

代码语言:javascript
复制
match age {
    x @ 0 => println!("0: {}", x),
    y @ 1 => println!("1: {}", y),
    z => println!("{}", z),
}

只要稍加扩展,同样的逻辑就可以应用于宏中的使用--我们是模式匹配的元组,但也可以将名称附加到特定的模式中。我想我甚至见过人们使用更类似的东西:(count @ ...。然而,http://danielkeep.github.io/tlborm/book/pat-internal-rules.html指出:

使用@的原因是,从RUST1.2开始,@令牌没有在前缀位置使用;因此,它不能与任何东西冲突。其他符号或唯一前缀可以按需要使用,但@的使用已经开始普及,因此使用它可以帮助读者理解您的代码。

而不仅仅是创建另一个顶级宏。

创建另一个宏可能是更好的实践,但只有在现代锈蚀。在最近对Rust进行了更改以使您可以直接导入宏之前,对于试图有选择地导入宏的最终用户来说,拥有多个宏可能是很棘手的。

另请参阅:

票数 15
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54406388

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档