如何编写递归macro_rules处理Rust中的嵌套slice?
问题分析与解决方案
错误原因
原宏的核心问题在于使用$arg:expr捕获slice内的元素:当元素是嵌套的slice(比如&[4,5])时,expr捕获器会将整个嵌套slice作为单一的token树处理。递归调用宏时,宏无法拆分这个token树的内部结构,只能匹配通用的$arg:expr分支,导致嵌套slice没有被递归展开。
修正后的宏实现
要实现嵌套slice的递归展开,需要改用基于token树的模式匹配,通过辅助宏拆分slice内的元素,避免expr捕获器的限制:
macro_rules! test { // 匹配顶层或嵌套的 &[元素列表],支持末尾可选逗号 (&[ $($rest:tt)* ]) => { &[test!(@parse_elements $($rest)*)].to_vec(); }; // 辅助宏:处理带逗号的元素列表,递归拆分每个元素 (@parse_elements $elem:tt, $($rest:tt)*) => { test!($elem), test!(@parse_elements $($rest)*) }; // 辅助宏:处理列表最后一个元素(无后续逗号) (@parse_elements $elem:tt) => { test!($elem) }; // 辅助宏:处理空列表(可选分支) (@parse_elements) => {}; // 处理非slice的单个元素 ($elem:expr) => { let a = $elem; }; }
验证展开结果
调用test!(&[&1, 2, 3, &[4, 5]]);时,宏会展开为:
&[let a = &1, let a = 2, let a = 3, &[let a = 4, let a = 5].to_vec()].to_vec();
完全符合预期效果。
内容的提问来源于stack exchange,提问作者ccQpein
相关产品推荐
相关产品推荐

