给定一个声明性 macro_rules!
接受任意数量参数的宏,如何根据重复扩展生成元组索引?
在下面的示例中,我想要 .0
在第 6 行和第 7 行生成。
(@replace $x:tt) => { $x; }
,但这在元组结构中不起作用。 std::integer_sequence
macro_rules! the_action {
(@replace $x:tt) => {$x;};
($($queue:expr),+) => {
let iters = ($($queue.iter()),+);
let options = ($(iters.0.next())*);
let values = ($(options.0.unwrap_or_default())*);
}
}
fn main() {
let a = [1, 4];
let b = [3, 2];
let c = [5, -1];
the_action!(a);
the_action!(a, b);
the_action!(a, b, c);
}
Playground link额外问题:鉴于 Rust 中缺少可变参数泛型,我希望这在 Rust 中很常见。为什么在 macro_rules 中没有用于重复索引的内置语法?编译器肯定有可用的信息。这是否曾在 RFC 中讨论过?
编辑:显然 it has ,但看起来它已被搁置。
最佳答案
据我所知,使用声明性宏生成它们是不可能的。
这取决于你的用例,但就目前而言,你可以从以下开始,每次解包元组:
macro_rules! the_action {
(@replace $x:tt) => {$x;};
($($queue:ident),+) => {
let ($(mut $queue,)+) = ($($queue.iter().copied(),)+);
let ($($queue,)+) = ($($queue.next(),)+);
let values = ($($queue.unwrap_or_default(),)*);
}
}
fn main() {
let a = [1, 4];
let b = [3, 2];
let c = [5, -1];
the_action!(a);
the_action!(a, b);
the_action!(a, b, c);
}
如果您需要访问中间步骤,您可以将它们打包到不同的结构中,如下所示:macro_rules! the_action {
(@replace $x:tt) => {$x;};
($($queue:ident),+) => {
{
struct Step1<$($queue,)+> {
$($queue: $queue,)+
}
let mut step1 = Step1{$($queue: $queue.iter().copied(),)+};
struct Step2<$($queue,)+> {
$($queue: $queue,)+
}
let step2 = Step2{$($queue: step1.$queue.next(),)+};
let values = ($(step2.$queue.unwrap_or_default(),)*);
}
}
}
fn main() {
let a = [1, 4];
let b = [3, 2];
let c = [5, -1];
the_action!(a);
the_action!(a, b);
the_action!(a, b, c);
}
一种替代方法是将元组解包到一个数组中,并使用索引——甚至不需要在宏观上创建索引。
关于rust - 基于宏规则生成元组索引!重复扩展,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66396814/