RUST宏编程入门

宏指示符

在Rust的宏编程中,宏可以接受多种类型的参数,称为"指示符"。这些指示符帮助宏识别不同类型的代码片段,并相应地处理它们。

这里列出全部指示符:

  • block
  • expr 用于表达式
  • ident 用于变量名或函数名
  • item
  • literal 用于字面常量
  • pat (模式 pattern)
  • path
  • stmt (语句 statement)
  • tt (标记树 token tree)
  • ty (类型 type)
  • vis (可见性描述符)

ident

ident:标识符,用于变量名、函数名、类型名等。

rust 复制代码
macro_rules! example {
    ($name:ident) => {
        let $name = 42;
    };
}
example!(x); // 展开为:let x = 42;

expr

expr:表达式,可以是任何合法的Rust表达式。

rust 复制代码
macro_rules! example {
    ($e:expr) => {
        println!("Result: {}", $e);
    };
}
example!(1 + 2); // 展开为:println!("Result: {}", 1 + 2);

ty

ty:类型,用于指定类型名称。

rust 复制代码
macro_rules! example {
    ($t:ty) => {
        let _x: $t;
    };
}
example!(i32); // 展开为:let _x: i32;

pat

pat:模式,用于模式匹配。

rust 复制代码
macro_rules! example {
    ($p:pat) => {
        match 42 {
            $p => println!("Matched!"),
            _ => println!("Not matched!"),
        }
    };
}
example!(x); // 展开为:match 42 { x => println!("Matched!"), _ => println!("Not matched!"), }

stmt

stmt:语句,用于单一语句。

rust 复制代码
macro_rules! example {
    ($s:stmt) => {
        $s
    };
}
example!(let x = 42;); // 展开为:let x = 42;

block

block:代码块,用于多个语句组成的代码块。

rust 复制代码
macro_rules! example {
    ($b:block) => {
        $b
    };
}
example!({
    let x = 42;
    println!("{}", x);
}); // 展开为:{ let x = 42; println!("{}", x); }

item

item:项,用于函数、结构体、模块等项。

rust 复制代码
macro_rules! example {
    ($i:item) => {
        $i
    };
}
example!(fn foo() {}); // 展开为:fn foo() {}

meta

meta:元数据项,用于属性。

rust 复制代码
macro_rules! example {
    ($m:meta) => {
        #[$m]
        fn foo() {}
    };
}
example!(test); // 展开为:#[test] fn foo() {}

tt

tt:令牌树,表示一个或多个令牌。

rust 复制代码
macro_rules! example {
    ($t:tt) => {
        $t
    };
}
example!(fn foo() {}); // 展开为:fn foo() {}

path

path :路径,用于路径(例如模块路径)。
rust macro_rules! example { ($p:path) => { let _: $p; }; } example!(std::io::Error); // 展开为:let _: std::io::Error;

literal

literal :字面量,用于常量值(字符串、数字等)。
rust macro_rules! example { ($l:literal) => { let x = $l; }; } example!("hello"); // 展开为:let x = "hello";

通过这些指示符,Rust的宏系统可以处理各种类型的输入,从而生成灵活且强大的代码。这些指示符使得宏在编写复杂代码时变得更加方便和可读。

代码示例

以下代码两个宏分别功能是创建函数和输出表达式及其结果

rust 复制代码
macro_rules! create_function {
    // 此宏接受一个 `ident` 指示符表示的参数,并创建一个名为 `$func_name` 的函数。
    // `ident` 指示符用于变量名或函数名
    ($func_name: ident) => (
        fn $func_name() {
            // `stringify!` 宏把 `ident` 转换成字符串。
            println!("You called {:?}()", stringify!($func_name))
        }
    )
}

// 借助上述宏来创建名为 `foo` 和 `bar` 的函数。
create_function!(foo);
create_function!(bar);

macro_rules! print_result {
    // 此宏接受一个 `expr` 类型的表达式,并将它作为字符串,连同其结果一起
    // 打印出来。
    // `expr` 指示符表示表达式。
    ($expression: expr) => (
        // `stringify!` 把表达式*原样*转换成一个字符串。
        println!("{:?} = {:?}", stringify!($expression), $expression)
    )
}

fn main() {
    foo();
    bar();

    print_result!(1u32 + 1);

    // 回想一下,代码块也是表达式!
    print_result!({
        let x = 1u32;
        x * x + 2 * x - 1
    });
}
``**
相关推荐
大白801 分钟前
为什么不要滥用 useMemo 和 useCallback?过度优化反而更卡
后端
aloha_1 分钟前
Linux服务器上指定目录的文件下载
前端
萧瑟余晖23 分钟前
Java深入解析篇三十六之分布式系统详解
java·开发语言·分布式
神奇小汤圆35 分钟前
Codex 子 Agent 配置指南:让 Sol 当军师,Luna 当搬砖工
后端
ClouGence38 分钟前
2026 年 4 款数据库管理工具推荐:免费、开源、付费怎么选?
数据库·后端·开源
ZJU_统一阿萨姆1 小时前
【推理优化进阶】调度器的数学内核:排队论、SLO 与在线决策
开发语言·人工智能·语言模型·系统架构·vllm
szp20051 小时前
为了在浏览器里跑多线程 ONNX 推理,我把自己的支付浮层弄挂了
前端·webassembly
大勇前进1 小时前
React 中 State 为什么不能直接修改?很多新手一直没懂
后端
大黄评测1 小时前
useState 与 useReducer 该怎么选?别只会无脑用 useState
后端
乐橙开放平台1 小时前
物业 SaaS 笔记:子账号 Policy 按通道隔离,At_ 管控面 / St_ 数据面治理 accessToken
后端·物联网·音视频