如何用Rust宏生成处理2的幂次的if-else-if分支链?
完善Rust递归宏实现以生成if-else-if分支
最终宏实现
macro_rules! generate_ifs { // 处理单个长度的分支:生成if块 + 最后的panic分支 ($buffer:ident, $e:literal) => { if $buffer.len() == $e { let mut buffer: [_; $e] = $buffer.try_into().unwrap(); real::rfft_$e(&mut buffer).to_vec() } else { panic!( "`microfft::real` only supports powers of 2 between 2 and 16384 for the amount of samples!" ) } }; // 处理多个长度的分支:生成当前if块,else递归处理剩余长度 ($buffer:ident, $e:literal, $($es:literal),+) => { if $buffer.len() == $e { let mut buffer: [_; $e] = $buffer.try_into().unwrap(); real::rfft_$e(&mut buffer).to_vec() } else { generate_ifs!($buffer, $($es),+) } }; }
使用示例
将原手动实现的calc函数替换为宏调用:
use microfft::Complex32; use microfft::real; pub(crate) fn calc(samples: &[f32]) -> Vec<Complex32> { let buffer = samples; generate_ifs!(buffer, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384) }
实现说明
递归逻辑设计
- 多参数分支:每次处理第一个长度值,生成对应的
if判断块,else部分递归调用宏处理剩余长度值,形成链式嵌套的if-else结构,等价于手写的if-else-if链。 - 单参数分支:处理最后一个长度值,生成对应的
if块后,追加统一的panic分支处理不支持的长度。
- 多参数分支:每次处理第一个长度值,生成对应的
核心代码复用
每个分支中重复的逻辑(类型转换、调用对应rfft_N函数、转Vec)通过宏参数$e动态生成:[_; $e]生成对应长度的固定数组类型real::rfft_$e自动拼接出对应长度的FFT函数名
效果等价性
宏展开后的代码和手写的if-else-if分支逻辑完全一致,编译器会自动优化嵌套的else-if为扁平分支,性能无差异。
内容的提问来源于stack exchange,提问作者phip1611
相关产品推荐
相关产品推荐

