This mistake comes up fairly frequently on URLO, such as
https://users.rust-lang.org/t/iterators-vs-index-loops-performance/52131?u=scottmcm
https://users.rust-lang.org/t/we-all-know-iter-is-faster-than-loop-but-why/51486/3?u=scottmcm
&mut Vec<_> &Vec<_>&Vec<_> one already exists]perf & style both seem appropriateWhat is the advantage of the recommended code over the original code
Vecs instead of only being able to pass entire onesVecFor example:
None.
fn use_for(vec: &mut Vec<usize>) {
for i in 0..vec.len() {
vec[i] = i;
}
}
Could be written as:
fn use_for(vec: &mut [usize]) {
for i in 0..vec.len() {
vec[i] = i;
}
}
I think its better if clipyy suggests using an iterator over the Vector. Changing a vec to an array might involve more code change than chaning a loop to an iterator.
Note that I'm not suggesting an array here, but a slice -- which is what code like .len() on a Vec is actually already using.
clippy will already suggest replacing the indexing with .iter_mut().enumerate(), but even with that change the parameter type should still change.
Ok. But I think that proposing .iter_mut().enumerate() is better than proposing taking a slice, because the latter is probably the bigger change.
I see this as a _both_, not an either-or.
I totally agree that
fn use_for(vec: &mut Vec<usize>) {
for i in 0..vec.len() {
vec[i] = i;
}
}
should change to
fn use_for(slice: &mut [usize]) {
for (i, x) in slice.iter_mut().enumerate() {
*x = i;
}
}
But this issue is just about one part. They're separable.
@Volker-Weissmann it does not require a change other than the type of the function parameter:
fn use_for(vec: &mut [usize]) {
for i in 0..vec.len() {
vec[i] = i;
}
}
fn main() {
let mut v = vec![1, 2, 3, 4, 5];
use_for(&mut v);
}
You can see in the playground too that Clippy will already suggest .iter_mut().enumerate().
EDIT: @scottmcm beat me to it :)
Clippy already suggests changing &Vec<..> to &[..]: ptr_arg
But it intentionally doesn't lint &mut args. We could start linting those to with the check for only-slice-methods.
Thanks, @flip1995 -- I hadn't checked that one. I've edited the OP.
Most helpful comment
@Volker-Weissmann it does not require a change other than the type of the function parameter:
(playground)
You can see in the playground too that Clippy will already suggest
.iter_mut().enumerate().EDIT: @scottmcm beat me to it :)