gpt4 book ai didi

rust - 如何编写带有可链接标记的宏?

转载 作者:行者123 更新时间:2023-11-29 08:19:21 26 4
gpt4 key购买 nike

我不太确定如何表达这个问题,所以问题标题很垃圾,但这是我正在尝试做的事情:

我可以写这个宏:

macro_rules! op(
( $v1:ident && $v2:ident ) => { Op::And($v1, $v2) };
( $v1:ident || $v2:ident ) => { Op::Or($v1, $v2) };
);

我可以这样使用:

let _ = op!(Expr || Expr);
let _ = op!(Expr && Expr);

我想做的是像这样写一个任意序列的标记:

let _ = op!(Expr || Expr || Expr && Expr || Expr);

它解析为标记的 Vec,例如:

vec!(T::Expr(e1), T::Or, T::Expr(e2), T::Or, ...) 

我可以写一个vec!像宏:

macro_rules! query(
( $( $x:expr ),* ) => {
{
let mut temp_vec = Vec::new();
$(temp_vec.push($x);)*
temp_vec
}
};
);

...但我看不到如何在宏运行时将任意符号(例如 &&)转换为标记。

这有可能吗?

围栏链接:http://is.gd/I9F5YV

最佳答案

似乎不可能在宏扩展期间捕获任意符号匹配:正如语言引用所说,“有效的指示符是 item、block、stmt、pat、expr、ty(类型)、ident、path、tt”。所以我最好的建议是使用“ident”-有效的标记,比如“and”/“or”而不是“&&”/“||”,例如:

macro_rules! query_op(
( and ) => { "T::And" };
( or ) => { "T::Or" };
( $e:ident ) => { concat!("T::Expr(", stringify!($e), ")") };
);

macro_rules! query(
( $( $x:ident )* ) => {
{
let mut temp_vec = Vec::new();
$(temp_vec.push(query_op!($x));)*
temp_vec
}
};
);

fn main() {
let q = query!(Expr1 or Expr2 and Expr3 or Expr4);
println!("{:?}", q);
}

输出:

["T::Expr(Expr1)", "T::Or", "T::Expr(Expr2)", "T::And", "T::Expr(Expr3)", "T::Or", "T::Expr(Expr4)"]

关于rust - 如何编写带有可链接标记的宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28793406/

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