如何让Rust的all()方法在空迭代器时返回false?
解决Rust中空迭代器
all()返回true的问题 Rust里空迭代器调用all()会返回true(这是逻辑上的空真特性),如果想让空场景返回false,有几种可行方案:
1. 针对字符串场景的直接判断
如果需求仅针对字符串,最简单的方式是先检查字符串是否为空,再结合all():
let s = ""; let result = !s.is_empty() && s.chars().all(|c| c == 'a'); assert_eq!(result, false); let s = "aaaa"; let result = !s.is_empty() && s.chars().all(|c| c == 'a'); assert_eq!(result, true);
2. 通用自定义all_non_empty函数(基于all()+标记位)
如果需要支持任意迭代器,可以写一个通用函数,通过标记位记录迭代器是否有元素,最后和all()的结果做与运算:
fn all_non_empty<I, F>(iter: I, mut f: F) -> bool where I: Iterator, F: FnMut(I::Item) -> bool, { let mut has_elements = false; iter.all(|item| { has_elements = true; f(item) }) && has_elements }
使用示例:
// 空迭代器 let empty_iter: Vec<i32> = vec![]; assert_eq!(all_non_empty(empty_iter.into_iter(), |x| x > 0), false); // 所有元素满足条件 let nums = vec![2,4,6]; assert_eq!(all_non_empty(nums.into_iter(), |x| x % 2 == 0), true); // 存在不满足条件的元素 let nums = vec![2,3,6]; assert_eq!(all_non_empty(nums.into_iter(), |x| x % 2 == 0), false);
3. 用Peekable提前检查是否为空
另一种通用方案是借助Peekable迭代器,先判断是否有元素,再执行all():
use std::iter::Peekable; fn all_non_empty<I, F>(mut iter: Peekable<I>, mut f: F) -> bool where I: Iterator, F: FnMut(I::Item) -> bool, { if iter.peek().is_none() { return false; } iter.all(f) }
使用示例:
let s = ""; assert_eq!(all_non_empty(s.chars().peekable(), |c| c == 'a'), false); let s = "aaab"; assert_eq!(all_non_empty(s.chars().peekable(), |c| c == 'a'), false);
内容的提问来源于stack exchange,提问作者Baron Leonardo
相关产品推荐
相关产品推荐

