gpt4 book ai didi

rust-如何将这个宏与循环/递归结合起来?

转载 作者:行者123 更新时间:2023-11-29 08:28:54 25 4
gpt4 key购买 nike

我有这样的代码:

macro_rules! match_token_pattern {
($parser:ident, $a:ident) => {{
let a = $parser.$a();

if a != None {
Some(a)
} else {
None
}
}};

($parser:ident, $a:ident, $b:ident) => {{
let a = $parser.$a();
let b = $parser.$b();

if a != None && b != None {
Some((a, b))
} else {
None
}
}};

($parser:ident, $a:ident, $b:ident, $c:ident) => {{
let a = $parser.$a();
let b = $parser.$b();
let c = $parser.$c();

if a != None && b != None && c != None {
Some((a, b, c))
} else {
None
}
}};
}

我可以将第二条/第三条规则合二为一吗?现在我正在尝试使用可变宏参数,但是宏结果()就像一些(a,一些(b,c))或一些(a,一些(b,一些(c,d)))......

谢谢。

最佳答案

我们可以从编写一个接受任意数量参数的宏开始:

macro_rules! match_token_patten {
($parser:ident, $($arg:ident),*)) => {{
/* macro body */
}};
}

$($arg:ident),* 将捕获任何数字标识符,以逗号分隔。

接下来,我们需要计算每种方法的结果。一个简单的方法是将它们存储在一个元组中,例如(parser.a(), parser.b(), parser.c())。我们将再次使用 $( ... ),* 语法来扩展捕获的可变参数:

macro_rules! match_token_patten {
($parser:ident, $($arg:ident),*)) => {{
let results = ( $( $parser.$arg() ),* );
}};
}

现在我们想把 (Some(x), Some(y), ...) 变成 Some((x, y, ...))。我们可以为此使用模式匹配!我们可以这样写:

if let (Some(a), Some(b), Some(c)) = results {
// only if results is a tuple of three Some values
Some((a, b, c)
} else {
// at least one of the results is None
None
}

最后,将其写成可变宏形式,我们得到:

macro_rules! match_token_pattern {
($parser:ident, $($a:ident),*) => {{
let results = ( $($parser.$a()),* );
if let ( $(Some($a)),* ) = results {
Some( ( $($a),* ) )
} else {
None
}
}};
}

关于rust-如何将这个宏与循环/递归结合起来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56399639/

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