Rust矩阵声明宏行数计算错误:单行场景适配问题求助
矩阵宏单行场景计数错误的问题分析与修复
问题原因分析
你的_count_semicolon宏逻辑存在缺陷,当处理单行矩阵(如matrix![1 2 3];)时,递归展开的计数逻辑失效:
- 单行输入时,
_count_semicolon!($($($n),+);+)会展开为_count_semicolon!(1,2,3;) - 该调用匹配宏的第二个规则,进一步展开为
_count!(_count_semicolon!([1,2,3];)) - 1 _count_semicolon!([1,2,3];)匹配第一个规则返回空,导致_count!()计算为0,最终因宏展开的token解析误差,错误得到行数为2,进而导致宽度计算错误
核心问题是这个宏试图通过包装行元素的间接方式计数行数,逻辑绕弯且边界场景处理失效。
修复方案
替换原有的计数宏,改用更直接的行计数逻辑,同时优化宏模式兼容更多输入写法:
// 计数矩阵总元素数量 macro_rules! _count_elements { () => (0usize); ($x:expr $($xs:expr)*) => (1usize + _count_elements!($($xs)*)); } // 计数矩阵行数 macro_rules! _count_rows { () => (0usize); // 匹配单行(无末尾分号) ($($n:expr) +) => (1usize); // 匹配单行(带末尾分号)或多行,递归计数剩余行 ($($n:expr) +; $($rest:tt)*) => (1usize + _count_rows!($($rest)*)); } macro_rules! matrix { // 兼容单行/多行,末尾分号可选 ($($($n:expr) +);* $(;)?) => {{ use std::rc::Rc; use crate::Matrix; let total_elements = _count_elements!($($($n)+)*); let row_count = _count_rows!($($($n)+);*); // 可选断言:确保每行元素数量一致,提前发现错误输入 debug_assert!(total_elements % row_count == 0, "矩阵每行元素数量必须一致"); Matrix { width: total_elements / row_count, height: row_count, data: Rc::new(vec![$($($n as f64),+),*].into_boxed_slice()), transpose: false } }}; }
关键改进点:
_count_rows宏:直接匹配单行/多行模式,递归计数行数,完美处理单行带/不带分号的边界场景- 宏模式优化:新增
$(;)?)支持单行末尾可选分号,兼容matrix![1 2 3]和matrix![1 2 3];两种写法 - 错误防护:添加
debug_assert!确保每行元素数量一致,提前捕获输入错误
测试验证
- 单行矩阵:
matrix![1 2 3];→ 行数=1,宽度=3/1=3,符合预期 - 多行矩阵:
matrix![1 2; 3 4];→ 行数=2,宽度=4/2=2,保持原有正确逻辑
内容的提问来源于stack exchange,提问作者J-Cake
相关产品推荐
相关产品推荐

