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
    });
}
``**
相关推荐
蜗牛快跑2136 分钟前
面向对象编程 vs 函数式编程
前端·函数式编程·面向对象编程
Dread_lxy7 分钟前
vue 依赖注入(Provide、Inject )和混入(mixins)
前端·javascript·vue.js
娅娅梨12 分钟前
C++ 错题本--not found for architecture x86_64 问题
开发语言·c++
汤米粥18 分钟前
小皮PHP连接数据库提示could not find driver
开发语言·php
冰淇淋烤布蕾21 分钟前
EasyExcel使用
java·开发语言·excel
拾荒的小海螺27 分钟前
JAVA:探索 EasyExcel 的技术指南
java·开发语言
涔溪1 小时前
Ecmascript(ES)标准
前端·elasticsearch·ecmascript
马剑威(威哥爱编程)1 小时前
哇喔!20种单例模式的实现与变异总结
java·开发语言·单例模式
榴莲千丞1 小时前
第8章利用CSS制作导航菜单
前端·css
白-胖-子1 小时前
【蓝桥等考C++真题】蓝桥杯等级考试C++组第13级L13真题原题(含答案)-统计数字
开发语言·c++·算法·蓝桥杯·等考·13级