Reputation: 8829
I am processing arrays in chunks of different sizes (3, 4, 5 etc.) (link to the playground):
fn main() {
let arr: [u8; 10] = [
1, 1, 1,
2, 2, 2,
3, 3, 3, 0
];
let mut results: [u8; 10] = [0; 10];
let corrections: [u8; 10] = [
1, 1, 1,
1, 1, 1,
1, 1, 1, 0
];
let group_ranges = vec![
0..3,
3..6,
6..10
];
for range in group_ranges {
let group_sum: u8 = arr[&range].iter().sum();
for (idx, el) in arr[&range].iter().enumerate() {
results[&range][idx] = el * group_sum * corrections[&range][idx];
}
}
println!("{:?}", results);
// => [3, 3, 3, 12, 12, 12, 27, 27, 27, 0]
}
The errors returned:
error[E0277]: the trait bound `&std::ops::Range<{integer}>: std::slice::SliceIndex<[u8]>` is not satisfied
--> src/main.rs:20:29
|
20 | let group_sum: u8 = arr[&range].iter().sum();
| ^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `&std::ops::Range<{integer}>`
= note: required because of the requirements on the impl of `std::ops::Index<&std::ops::Range<{integer}>>` for `[u8]`
error[E0277]: the trait bound `&std::ops::Range<{integer}>: std::slice::SliceIndex<[u8]>` is not satisfied
--> src/main.rs:21:26
|
21 | for (idx, el) in arr[&range].iter().enumerate() {
| ^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `&std::ops::Range<{integer}>`
= note: required because of the requirements on the impl of `std::ops::Index<&std::ops::Range<{integer}>>` for `[u8]`
error[E0277]: the trait bound `&std::ops::Range<{integer}>: std::slice::SliceIndex<[u8]>` is not satisfied
--> src/main.rs:22:13
|
22 | results[&range][idx] = el * group_sum * corrections[&range][idx];
| ^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `&std::ops::Range<{integer}>`
= note: required because of the requirements on the impl of `std::ops::Index<&std::ops::Range<{integer}>>` for `[u8]`
error[E0277]: the trait bound `&std::ops::Range<{integer}>: std::slice::SliceIndex<[u8]>` is not satisfied
--> src/main.rs:22:53
|
22 | results[&range][idx] = el * group_sum * corrections[&range][idx];
| ^^^^^^^^^^^^^^^^^^^ slice indices are of type `usize` or ranges of `usize`
|
= help: the trait `std::slice::SliceIndex<[u8]>` is not implemented for `&std::ops::Range<{integer}>`
= note: required because of the requirements on the impl of `std::ops::Index<&std::ops::Range<{integer}>>` for `[u8]`
Using range
instead of &range
yields the use of moved value
error. Is it possible to work without using range.clone()
all over?
Upvotes: 2
Views: 724
Reputation: 430991
No, it is not currently possible. The valid values to pass to a slice's index
method (a.k.a. []
) are those types which implement the SliceIndex
trait. &Range
is not in that list, although I don't know if there's any technical reason that prevents it from being the case.
An aside on the performance of cloning in this case...
When you call foo[1..2]
, you are passing ownership of the created Range<usize>
into Index::index
, which takes up two usize
values. If we were able to pass in a &Range
, we'd only be passing in a single usize
worth, but we'd have to perform a dereference and then probably copy at least one of the inner usize
s anyway. My (untested) hypothesis is that it would be slower than cloning anyway.
See also
Upvotes: 4