Rust中如何约束泛型T支持模运算以实现迭代器偶数过滤?
问题原因
你的代码编译失败核心有两个问题:
filter方法传给闭包的参数是迭代器元素的引用(&T类型),而你为T实现的Remtrait不支持对引用类型做取模运算,类型不匹配。- 代码中的
2和0是整型字面量,Rust无法自动将其转换为泛型T的类型,且编译器提示的{integer}占位符不能直接写在trait约束中,属于不合法语法。
原生解决方案
不需要引入任何第三方依赖,仅用标准库内置trait即可实现需求,有两种常用实现方式:
方案1:适配大部分常用整数类型
通过From<u8>约束实现整数转换,适用于所有位宽大于等于8位的无符号整数、以及位宽大于等于16位的有符号整数:
pub fn evens<T>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = T> where T: std::ops::Rem<Output = T> + std::cmp::PartialEq + From<u8>, { // 注意原判断条件!=0是筛选奇数,已改为==0匹配偶数需求 iter.filter(|&x| x % T::from(2) == T::from(0)) }
方案2:兼容所有原生整数类型
如果需要兼容i8这类位宽较小的有符号整数,可以换用From<bool>构造0和2,所有原生整数类型都默认实现了bool到自身的无损转换:
pub fn evens<T>(iter: impl Iterator<Item = T>) -> impl Iterator<Item = T> where T: std::ops::Rem<Output = T> + std::cmp::PartialEq + std::ops::Add<Output = T> + From<bool>, { let zero = T::from(false); let two = T::from(true) + T::from(true); iter.filter(move |&x| x % two == zero) }
测试示例
两种方案都可以直接用常规整数类型调用:
fn main() { let nums = vec![1, 2, 3, 4, 5, 6]; let even_nums: Vec<i32> = evens(nums.into_iter()).collect(); assert_eq!(even_nums, vec![2, 4, 6]); }
内容的提问来源于stack exchange,提问作者Brian Kessler
相关产品推荐
相关产品推荐

