Rust中for循环工作机制:为何兼容IntoIterator与Iterator?
Rust中for循环同时支持IntoIterator和Iterator的原因
《Rust语言参考手册》中描述for循环的语法脱糖逻辑是:对in关键字后的表达式调用IntoIterator::into_iter来获取迭代器,再遍历该迭代器的元素。但实际使用中,我们发现for循环对实现了IntoIterator或Iterator的表达式都能正常工作,比如:
let v = vec!(1, 2, 3); // 两种写法均可正常运行: for i in v { /* ... */ } // v 实现 IntoIterator for i in v.into_iter() { /* ... */ } // v.into_iter() 实现 Iterator
这看起来似乎和文档描述不符,于是产生疑问:是文档描述不全、IntoIterator::into_iter有特殊处理、Iterator也实现了IntoIterator,还是自身理解有误?
答案是所有实现了Iterator的类型,标准库都自动为它们实现了IntoIterator,这就是两种写法都能工作的核心原因。
标准库中的默认实现大致如下:
impl<I: Iterator> IntoIterator for I { type Item = I::Item; type IntoIter = I; fn into_iter(self) -> Self::IntoIter { self } }
也就是说,当你把一个Iterator类型的值放到for循环的in后面时,编译器依然会按照参考手册描述的逻辑调用IntoIterator::into_iter,但这个调用只是直接返回迭代器自身,相当于没有额外操作。
所以参考手册的描述是准确的,并没有矛盾——两种写法最终都走的是IntoIterator的路径,只是Iterator类型的into_iter实现是返回自身而已。
内容的提问来源于stack exchange,提问作者Aiueiia
相关产品推荐
相关产品推荐

