Rust 宏 macro

Rust About 1,150 words

声明宏 Declarative Macro

使用acro_rules!,允许用户以声明性的(declarative)方式定义句法扩展。

每个声明宏都有一个名称和一条或多条规则。每条规则都有两部分:一个匹配器(matcher),描述它匹配的句法;一个转码器(transcriber),描述成功匹配后将执行的替代调用句法。

// 这是一个简单的宏,名为 `say_hello`。
macro_rules! say_hello {
    // `()` 表示此宏不接受任何参数。
    () => (
        // 此宏将会展开成这个代码块里面的内容。
        println!("Hello!");
    )
}

vec!宏原理

let v: Vec<u32> = vec![1, 2, 3];

#[macro_export]
macro_rules! vec {
    ( $( $x:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push($x);
            )*
            temp_vec
        }
    };
}

过程宏 Procedural Macro

过程宏分为三种:

  • 自定义#[derive]宏:在结构体和枚举上指定通过 derive 属性添加的代码。
  • 类属性宏(Attribute-like):自定义属性,用于任意条目(Item)。
  • 类函数宏(Function-like):看起来像函数调用,但在指定为参数的token上操作。

非叶节点 (non-leaf) 的标记树:即 (...)、[...] 或 {...}。

编译器总是将语法拓展的展开结果看作完整的 AST 节点,而不是仅仅把它视为一列标记。

macro_rules! $name {
    $rule0 ;
    $rule1 ;
    // …
    $ruleN ;
}

规则里你可以使用大/中/小括号: braces {}、brackets []、parentheses ()。每条“规则”都形如:

```rust
($matcher) => {$expansion}

在规则里选择哪种括号并不会影响宏调用。


假如调用 m! 这个宏,如果该宏展开成条目,则必须使用 m! { ... } 或者 m!( ... );; 如果该宏展开成表达式,你可以使用 m! { ... } 或者 m!( ... ) 或者 m![ ... ]。
Views: 1,178 · Posted: 2023-04-23

————        END        ————

Give me a Star, Thanks:)

https://github.com/fendoudebb/LiteNote

扫描下方二维码关注公众号和小程序↓↓↓

扫描下方二维码关注公众号和小程序↓↓↓


Today On History
Browsing Refresh