用声明式宏解析 Rust 语法
2023/6/17 1:22:15
本文主要是介绍用声明式宏解析 Rust 语法,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
在上一篇 Rust 声明式宏中的 Metavariables 有哪些 的基础上,
今天尝试解析一下 Rust 中的几种 item。我们知道一个 crate 是由 item 组成的,每一个 fn
struct
enum
impl
mod
等定义都是一个 item,
这篇文章就简单解析一下 Function
和 struct
Function
先看一个最简单的函数
fn foo() {}
这个 foo
函数由关键字 fn
开头,后面跟一个函数名($function_name: ident), 然后是一对 ()
, 再跟一个函数体 block
macro_rules! function_item_matcher { (fn $name: ident () $block: block) => { fn $name() $block }; } function_item_matcher! { fn hello(){ println!("hello"); } }
再复杂一点,给我们的 foo
函数加点料
#[allow(unused_variables)] pub async fn foo(arg1: u8) -> u8 { arg1 }
我们的 foo
函数已经具备了常见函数的基本形态,除了没有泛型等比较复杂的部分,这里了解分析方法就行,有需要的话再继续抽丝剥茧即可。
完整的 Function
的语法定义看这里: https://doc.rust-lang.org/reference/items/functions.html
macro_rules! function_item_matcher { ( #[$meta: meta] $vis: vis async fn $name: ident ($arg: ident : $ty: ty) -> $ret:ty $block: block ) => { #[$meta] $vis async fn $name($arg: $ty) -> $ret $block }; }
如果 meta 的个数和 argument 的个数都不确定呢
#[allow(unused_variables)] #[allow(dead_code)] pub async fn foo(arg1: u8, arg2: u32, ) -> u8 { arg1 }
好,那就再改一改:
macro_rules! function_item_matcher { ( $(#[$meta: meta])* $vis: vis async fn $name: ident ($($arg: ident : $ty: ty),* $(,)?) -> $ret:ty $block: block ) => { $(#[$meta])* $vis async fn $name($($arg: $ty),*) -> $ret $block }; }
还有个问题,这个 async 直接写下来的,要是没有 async 呢? 只需要加一个分支就好
macro_rules! function_item_matcher { ( $(#[$meta: meta])* $vis: vis async fn $name: ident ($($arg: ident : $ty: ty),* $(,)?) -> $ret:ty $block: block ) => { $(#[$meta])* $vis async fn $name($($arg: $ty),*) -> $ret $block }; ( $(#[$meta: meta])* $vis: vis fn $name: ident ($($arg: ident : $ty: ty),* $(,)?) -> $ret:ty $block: block ) => { $(#[$meta])* $vis fn $name($($arg: $ty),*) -> $ret $block }; }
这样做不过是把我定义的函数照搬下来,有什么好处呢?好处就是你可以随意插入自己的代码
macro_rules! function_item_matcher { ( $(#[$meta: meta])* $vis: vis fn $name: ident ($($arg: ident : $ty: ty),* $(,)?) -> $ret:ty $block: block ) => { println!("definition: {}({})", stringify!($name), stringify!($($arg: $ty),*)); $(#[$meta])* $vis fn $name($($arg: $ty),*) -> $ret { print!("calling: {}(", stringify!($name)); $(print!("{},", $arg);)* println!(")"); $block } }; } function_item_matcher!{ #[allow(unused_variables)] #[allow(dead_code)] pub fn foo(arg1: u8, arg2: u32, ) -> u8 { arg1 } } foo(9, 8);
输出
definition: foo(arg1 : u8, arg2 : u32) calling: foo(9,8,)
struct
struct 有两种
// struct struct #[...] struct A { ... } // tuple struct #[...] struct B(...);
所以对于第一种:
macro_rules! struct_item_matcher { ( $(#[$meta: meta])* $vis: vis struct $name: ident { $( $(#[$field_meta: meta])* $field_vis: vis $field_name: ident : $field_ty: ty ),* $(,)? } ) => { $(#[$meta])* $vis struct $name { $( $(#[$field_meta])* $field_vis $field_name: $field_ty ),* } }; // 针对 struct A; 的情况 ( $(#[$meta: meta])* $vis: vis struct $name: ident; ) => { $(#[$meta])* $vis struct $name; } }
对于第二种 tuple struct
的情况处理起来大同小异,我就不写了 😂
这篇关于用声明式宏解析 Rust 语法的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-23JAVA语音识别项目入门教程
- 2024-11-23Java云原生学习:从入门到实践
- 2024-11-22Java创业学习:初学者的全面指南
- 2024-11-22JAVA创业学习:零基础入门到实战应用教程
- 2024-11-22Java创业学习:从零开始的Java编程入门教程
- 2024-11-22Java对接阿里云智能语音服务学习教程
- 2024-11-22JAVA对接阿里云智能语音服务学习教程
- 2024-11-22Java对接阿里云智能语音服务学习教程
- 2024-11-22Java副业学习:零基础入门到实战项目
- 2024-11-22Java副业学习:零基础入门指南