Rust:从Iterator<Item=&T>收集为Vec<T>的更优实现方法
Rust:更简洁实现移除数组每隔一个元素的函数
我尝试编写一个移除数组中每隔一个元素的函数,初始代码如下:
fn remove_every_other(arr: &[u8]) -> Vec<u8> { arr.iter().step_by(2).collect::<Vec<_>>() }
但遇到类型不匹配错误:
| 1 | fn remove_every_other(arr: &[u8]) -> Vec<u8> { | ------- expected `Vec<u8>` because of return type 2 | arr.iter().step_by(2).collect::<Vec<_>>() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `u8`, found `&u8` | = note: expected struct `Vec<u8>` found struct `Vec<&u8>`
我通过map解引用解决了问题,但觉得写法不够简洁:
arr.iter().step_by(2).map(|x| *x).collect::<Vec<_>>()
尝试使用into_iter(文档说明其返回T而非&T),但仍出现相同错误。请问是否有更简洁的实现方式?
更简洁的实现方式
1. 使用copied()
由于u8实现了Copy trait,可以直接用copied()将迭代器中的&u8转换为u8,写法更简洁直观:
fn remove_every_other(arr: &[u8]) -> Vec<u8> { arr.iter().step_by(2).copied().collect() }
copied()会对迭代器中的每个引用类型元素执行复制操作,对于Copy类型来说,这比手动解引用更高效且易读。
2. 使用cloned()
如果处理的类型实现了Clone而非Copy,可以用cloned()替代,对于u8这类Copy类型,cloned()同样适用:
fn remove_every_other(arr: &[u8]) -> Vec<u8> { arr.iter().step_by(2).cloned().collect() }
关于into_iter的问题说明
函数参数是&[u8](切片的引用),此时调用into_iter()和iter()的效果完全一致,都会生成&u8类型的迭代器。只有当你拥有切片的所有权(比如参数是Vec<u8>)时,into_iter()才会生成u8类型的迭代器。
内容的提问来源于stack exchange,提问作者k-tten
相关产品推荐
相关产品推荐

