Rust中Iterator::chain使用疑问:map闭包i+1为何触发编译错误?
Rust Chain迭代器类型不匹配问题解释与解决方案
核心原因:Chain要求两个迭代器的Item类型完全一致
Iterator::chain方法的核心约束是拼接的两个迭代器必须产生相同类型的元素,这是两段代码运行结果不同的根本原因:
代码片段1的类型匹配逻辑
v.iter()返回的迭代器元素类型是&i32(对Vec中元素的不可变引用)[6,7,8,9,10].iter()同样返回元素类型为&i32的迭代器- 闭包
|i| i直接返回&i32类型的参数,因此map后的迭代器元素类型仍为&i32 - 两个迭代器的元素类型完全一致,
Chain可以正常拼接
代码片段2的类型不匹配逻辑
- 闭包
|i| i+1中,i是&i32类型,Rust会自动对引用执行解引用强制转换来支持算术运算,因此i+1的结果是i32类型(所有权类型) - 此时
map后的迭代器元素类型为i32,而前面v.iter()的元素类型是&i32,两者类型不匹配,违反了Chain的约束,导致编译错误
- 闭包
修复方案
根据需求选择以下任意一种方式,让两个迭代器的元素类型统一:
方案1:让两个迭代器都返回所有权类型(i32)
将v.iter()改为v.into_iter()(获取Vec元素的所有权),同时调整闭包接收引用并解引用:
fn main() { let v: Vec<_> = (1..5).collect(); let u = v.into_iter().chain([6, 7, 8, 9, 10].iter().map(|&i| i + 1)); u.for_each(|i| println!("{i}")); }
方案2:让两个迭代器都返回引用类型(&i32)
提前计算好数组元素的值,再通过iter()生成引用迭代器:
fn main() { let v: Vec<_> = (1..5).collect(); let u = v.iter().chain([7, 8, 9, 10, 11].iter()); u.for_each(|i| println!("{i}")); }
注意:不要尝试用
map(|i| &(i+1))的方式生成引用,因为i+1是临时值,引用会在闭包结束后失效,引发生命周期错误。
内容的提问来源于stack exchange,提问作者Amir reza Riahi
相关产品推荐
相关产品推荐

