gpt4 book ai didi

rust - 将宏参数传递给其他宏

转载 作者:行者123 更新时间:2023-12-03 11:28:12 27 4
gpt4 key购买 nike

我是 Rust 新手。我正在尝试创建宏,它需要一个缓冲区,然后从中解码一些数据并创建给定的变量列表。如果发生错误,那么它应该打印错误并继续,因为我将在接收缓冲区的循环中调用它。像这样的东西:-

for bin_ref in bufs {

extract!( bin_ref anime &str episodes u32 season u32);

//if everything goes ok then do some cool stuff with
//above variables otherwise take next buf_ref
}

我该怎么做?所以我采用了这种方法:-

#[macro_export]
macro_rules! extract {

( $buf:ident $($var:ident $typ:ty),* ) => {
$(
ext_type!( $buf $var $typ );
)*
};
}

#[macro_export]
macro_rules! ext_type {
( $buf:ident $var:ident &str ) => {

let mut $var : &str = ""; //some string specific function
println!("doing cool things with '{}' which is string ",$var);

};
( $buf:ident $var:ident u32 ) => {
let mut $var : u32 = 34; //some u32 specific function
println!("doing cool things with '{}' which is u32",$var);
}
}

我有以下测试功能:-

fn macro_test() {

let mut bin_ref : &[u8] = &[0u8;100];

ext_type!(bin_ref anime &str); // works
ext_type!(bin_ref episodes u32 ); // works

extract!( bin_ref username &str, password &str ); // does not work. why ??
}

当我编译这个时,我收到以下错误:-

error: no rules expected the token `&str`
--> src/easycode.rs:11:34
|
11 | ext_type!( $buf $var $typ );
| ^^^^ no rules expected this token in macro call
...
19 | macro_rules! ext_type {
| --------------------- when calling this macro
...
48 | extract!( bin_ref username &str, password &str );
| ------------------------------------------------- in this macro invocation

为什么我不能将 $typ 传递给 ext_type! 宏?从代码调用时它可以工作

最佳答案

ext_type!宏的规则需要文字标记 &stru32在最后。这些文字标记无法匹配匹配的片段$typ:tyextract! 。为了成功地将文字标记与匹配的片段匹配,it must be a tt , ident or lifetime .

在这种情况下唯一有效的选项是 tt ,简单地说,只是一个解析器标记。然而,一种类型通常由多个标记组成;例证&str ,由两个 token & 组成和str 。因此,我们必须使用重复来完全捕获 tt 的类型。号:$($typ:tt)+会做得很好。

使用 tt 进行无限重复然而,这是有代价的——tt将匹配几乎所有内容,因此只需替换 $typ:ty$($typ:tt)+将不起作用,如 $typ重复将捕获所有内容,直到宏调用结束!为了防止这种情况发生,我们必须delimit宏规则匹配器中的类型标记树以阻止其消耗所有内容。以使调用稍微冗长为代价,将重复内容括在括号中将对我们很有帮助,并阻止 token 树完全匹配我们想要的位置。修改后的宏如下所示:

#[macro_export]
macro_rules! extract {
( $buf:ident $($var:ident ($($typ:tt)+)),* ) => {
$(
ext_type!( $buf $var $($typ)+);
)*
};
}

注意 $typ:ty 的替换与 ($($typ:tt)+) (这是一个用括号括起来的标记树重复)在匹配器中,并替换 $typ$($typ)+在转录器中。

宏规则调用如下:

extract!(bin_ref username (&str), password (&str), id (u32));

Rust Playground

关于rust - 将宏参数传递给其他宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63204735/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com