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
    });
}
``**
相关推荐
djarmy1 小时前
MAIN.c(1): warning C318: can’t open file ‘STC8G.H’ 报错 解决 分析
c语言·开发语言·mongodb
传奇开心果编程2 小时前
【Xilem 0.4 基础语法学与练】第一课:从零到计数器
学习·rust·前端框架
HEJOO92 小时前
深入理解 Java volatile 关键字:原理、用法与常见误区
java·开发语言·spring
曹牧2 小时前
Java:no content to map due to end of input
java·开发语言
子非鱼a2 小时前
【WEB】multiSQL
前端
梦梦代码精2 小时前
《回收租赁系统技术选型避坑指南:业务闭环与二开自由度详解》
开发语言·低代码·docker·开源·代码规范
两点王爷2 小时前
SpringBoot 项目集成 GeoServer 源码,实现地图服务发布
java·spring boot·后端
隔窗听雨眠2 小时前
记一次SQL Server数据库性能分析:从CPU100%到单配置修复的完整诊断
开发语言·数据库·php
David猪大卫2 小时前
【C++修炼】智能指针使用及原理
开发语言·c++·经验分享·笔记·学习·考研·面试
charlie1145141912 小时前
现代Qt开发之图像处理进阶:像素操作与格式转换
开发语言·图像处理·qt