I'm trying to implement the Index trait for a struct that I've defined in my crate. I want my struct to be able to be either the owner of a vec, or have a reference (or mutable reference) to a vec as one of it's fields so I've defined that field as a generic type like so:
use std::ops::{Index, IndexMut};
#[derive(Debug)]
struct BackPack<V> {
data: V,
}
impl<V, T> Index<usize> for BackPack<V>
where
V: Index<usize, Output = T>+IndexMut<usize, Output = T>,
{
type Output = T;
fn index(&self, rhs: usize) -> &Self::Output {
&self.data[rhs]
}
}
This implementation works if I give ownership of the vec to the struct like this:
fn main() {
let mut a = vec![0; 100];
{
let b3 = BackPack{
data: a,
};
println!("{:?}", b3[5]);
}
}
But gives me an error if I try to do this:
fn main() {
let mut a = vec![0; 100];
{
let b1 = BackPack{
data: &a,
};
println!("{:?}", b1[5]);
}
}
cannot index into a value of type `BackPack<&std::vec::Vec<{integer}>>`rustc(E0608)
I can update my Index
impl to be this (change V
to &V
in the impl line):
impl<V, T> Index<usize> for BackPack<&V>
where
V: Index<usize, Output = T>+IndexMut<usize, Output = T>,
{
type Output = T;
fn index(&self, rhs: usize) -> &Self::Output {
&self.data[rhs]
}
}
Which basically swaps the errors - now the version of main where I give ownership of the vec to my Backpack gives the cannot index...
error, but the reference version works.
So... I tried just creating two implementations of the Index
trait (one for BackPack<V>
and another for BackPack<&V>
) but this gives a new error:
conflicting implementations of trait `std::ops::Index<usize>` for type `BackPack<&_>`
note: downstream crates may implement trait `std::ops::Index<usize>` for type `&_`
Am I attempting to do something that is fundamentally impossible? Is there a way that I could change this implementation so it could accomplish what I'm hoping to do? Thank you!