Reputation: 1776
I'm trying to implement the Index
trait for a simple trait, and I want to use it with usize
. I added SliceIndex<[T], Output = T>
so I can use T
to index the slice
inside A
.
use std::ops::Index;
use std::slice::SliceIndex;
struct A <'a, T>{
slice: &'a [T]
}
impl<'a, T: Index<T, Output = T> + SliceIndex<[T], Output = T>> Index<T>
for A<'a, T>
{
type Output = T;
#[inline(always)]
fn index(&self, index: T) -> &Self::Output {
self.slice.index(index)
}
}
fn main() {
let mut aa: Vec<u64> = vec![0; 10];
let coefficient_iterable = A{slice: &aa};
println!("{}", coefficient_iterable[1usize]);
}
But I get:
Error:
error[E0608]: cannot index into a value of type `A<'_, u64>`
--> src/main.rs:22:20
|
22 | println!("{}", coefficient_iterable[1usize]);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
For more information about this error, try `rustc --explain E0608`.
error: could not compile `playground` due to previous error
I have no idea why, since usize
implements SliceIndex<[T]>
.
Upvotes: 5
Views: 7382
Reputation: 26767
Requiring T
to be both Index
and SliceIndex
doesn't make sense because Index
describes the behaviour of indexable containers, while SliceIndex
is a bound you can put on a generic indexing type to make it more flexible.
You don't want to implement Index<T>
because T
here is the type of the items in the slice, not the type of the index. For the code in your main
function to work you could just implement Index<usize>
, but generically implementing Index<Idx>
(where Idx: SliceIndex
) gives more flexibility so you can use ranges too.
use std::ops::Index;
use std::slice::SliceIndex;
struct A<'a, T> {
slice: &'a [T],
}
impl<'a, T, Idx> Index<Idx> for A<'a, T>
where
Idx: SliceIndex<[T], Output = T>,
{
type Output = T;
#[inline(always)]
fn index(&self, index: Idx) -> &Self::Output {
self.slice.index(index)
}
}
fn main() {
let aa: Vec<u64> = vec![0; 10];
let coefficient_iterable = A { slice: &aa };
assert_eq!(coefficient_iterable[1], 0);
}
Upvotes: 9