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
    });
}
``**
相关推荐
枫叶kx几秒前
发布一个angular的npm包(包含多个模块)
前端·npm·angular.js
工呈士1 分钟前
Webpack 剖析与策略
前端·面试·webpack
lyc2333332 分钟前
鸿蒙Next智能家居:轻量化模型的场景化落地
前端
天生我材必有用_吴用3 分钟前
Three.js开发必备:几何体BufferGeometry顶点详解
前端
憨憨是条狗3 分钟前
Vue + Vant H5 应用中实现 SSE 实时通知及系统通知功能
前端
dremtri3 分钟前
双 Token 认证机制详解与完整 Demo
前端·后端
CnLiang4 分钟前
fnm无缝切换项目的pnpm和node脚本化实践
前端·javascript
设计师也学前端6 分钟前
SVG数据可视化组件基础教程:带刻度的仪表盘2
前端
柚子8167 分钟前
CSS也支持if了
前端·css
一棵白菜8 分钟前
Iterm2 终端安装(带语法提示)
前端