我可以创建一个展开循环的宏吗?
Can I create a macro that unrolls loops?
我正在尝试用 Rust 编写一些快速矩阵代码,为此需要确保展开循环。有没有办法创建编译时 for 循环?例如:我要
unroll_loop!(f, a, 3);
生成
f(a, 0);
f(a, 1);
f(a, 2);
嗯,有点。
macro_rules! unroll {
(0, |$i:ident| $s:stmt) => {};
(1, |$i:ident| $s:stmt) => {{ let $i: usize = 0; $s; }};
(2, |$i:ident| $s:stmt) => {{ unroll!(1, |$i| $s); let $i: usize = 1; $s; }};
(3, |$i:ident| $s:stmt) => {{ unroll!(2, |$i| $s); let $i: usize = 2; $s; }};
(4, |$i:ident| $s:stmt) => {{ unroll!(3, |$i| $s); let $i: usize = 3; $s; }};
// ...
}
fn main() {
unroll!(3, |i| println!("i: {}", i));
}
您可能想问 "why don't you just use unroll!($i-1, |$i| $s)
for the recursive case?"。这是因为 宏不能做数学运算 。事实上,他们不能任何形式的评估无论如何。你基本上仅限于符号操作。
宏也不能以任何方式与类型或值交互,这意味着下面的不起作用,也无法使其起作用:
const N: usize = 3;
unroll!(N, |i| println!("i: {}", i));
因此,您可以 执行此操作,但仅限于文字整数,并且您必须在宏中为每个要使用的整数编写一个明确的案例。
我正在尝试用 Rust 编写一些快速矩阵代码,为此需要确保展开循环。有没有办法创建编译时 for 循环?例如:我要
unroll_loop!(f, a, 3);
生成
f(a, 0);
f(a, 1);
f(a, 2);
嗯,有点。
macro_rules! unroll {
(0, |$i:ident| $s:stmt) => {};
(1, |$i:ident| $s:stmt) => {{ let $i: usize = 0; $s; }};
(2, |$i:ident| $s:stmt) => {{ unroll!(1, |$i| $s); let $i: usize = 1; $s; }};
(3, |$i:ident| $s:stmt) => {{ unroll!(2, |$i| $s); let $i: usize = 2; $s; }};
(4, |$i:ident| $s:stmt) => {{ unroll!(3, |$i| $s); let $i: usize = 3; $s; }};
// ...
}
fn main() {
unroll!(3, |i| println!("i: {}", i));
}
您可能想问 "why don't you just use unroll!($i-1, |$i| $s)
for the recursive case?"。这是因为 宏不能做数学运算 。事实上,他们不能任何形式的评估无论如何。你基本上仅限于符号操作。
宏也不能以任何方式与类型或值交互,这意味着下面的不起作用,也无法使其起作用:
const N: usize = 3;
unroll!(N, |i| println!("i: {}", i));
因此,您可以 执行此操作,但仅限于文字整数,并且您必须在宏中为每个要使用的整数编写一个明确的案例。