Rust中按正负零拆分Vec后结果为空的原因及解决方法
Rust Vec拆分问题:为何正数/负数/零集合为空?
问题重现
尝试将存储i32的Vec拆分为正数、负数、零三个集合,使用以下代码:
let (mut n, mut p, mut z) = (Vec::new(), Vec::new(), Vec::new()); nums.iter() // 返回nums中每个元素的&i32引用 .map(|num| { match num == &0 { true => z.push(*num), // 解引用后存入零集合z _ => match num > &0 { true => p.push(*num), // 存入正数集合p _ => n.push(*num) // 存入负数集合n } } }); println!("p {:?}, n {:?}, z {:?}", p, n, z);
运行后输出全为空集合:
p [], n [], z []
原因分析
Rust的迭代器是惰性求值的:map方法仅定义了元素的转换逻辑,但不会主动遍历迭代器执行闭包内的代码。只有调用消费型迭代器方法(如for_each、collect、count等)时,迭代器才会被遍历,闭包中的逻辑才会实际执行。
你的代码仅调用了map,没有触发迭代器的消费流程,因此闭包里的push操作完全没执行,三个集合自然为空。
修复方案
方案1:替换map为for_each
for_each是专门用于执行副作用(如修改外部变量)的消费型方法,会遍历每个元素并执行闭包逻辑:
let (mut n, mut p, mut z) = (Vec::new(), Vec::new(), Vec::new()); nums.iter() .for_each(|num| { match num == &0 { true => z.push(*num), _ => match num > &0 { true => p.push(*num), _ => n.push(*num) } } }); println!("p {:?}, n {:?}, z {:?}", p, n, z);
方案2:简化匹配逻辑(更推荐)
直接对解引用后的数值进行匹配,让代码更简洁清晰:
let (mut negatives, mut positives, mut zeros) = (Vec::new(), Vec::new(), Vec::new()); nums.iter() .for_each(|&num| { // 直接解引用获取i32值 match num { 0 => zeros.push(num), x if x > 0 => positives.push(x), _ => negatives.push(num), } }); println!("positives {:?}, negatives {:?}, zeros {:?}", positives, negatives, zeros);
方案3:手动遍历(最直观)
如果不习惯迭代器方法,也可以用普通for循环实现:
let (mut negatives, mut positives, mut zeros) = (Vec::new(), Vec::new(), Vec::new()); for &num in &nums { match num { 0 => zeros.push(num), x if x > 0 => positives.push(x), _ => negatives.push(num), } } println!("positives {:?}, negatives {:?}, zeros {:?}", positives, negatives, zeros);
内容的提问来源于stack exchange,提问作者Jim
相关产品推荐
相关产品推荐

