Extend my get function for slices

I have a MapTrait<T> which has an implementation fn data() which returns &[T].
T: Sized + Default + Clone + Copy

Is it possible to extend this function down here to make it accept a single value as well as a range?
As in std rust for slices?
Thus returning a single value or slice.

pub trait MapTrait<T>
where
    T: Sized + Default + Clone + Copy
{
    fn get(&self, idx: usize) -> Option<&T>
    {
        self.data().get(idx)
    }
}

Something like this but this one is wrong.
I get errors like "parameter T may not live long enough" (which i do not understand)

fn get2<I>(&self, idx: I) -> Option<&I::Output>
where I: SliceIndex<[T]>
{
    self.data().get(idx)
}

Did you mean -> Option<&[T]>? The method as presented can't return a &[_] because of the Sized bound.


Are you just trying to ape the Index traits?

When I add 'static to my T it works.
The current get returns one element fn get(&self, idx: usize) -> Option<&T>

I was trying to ape the slice function. But maybe that is the wrong approach...

    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline]
    #[must_use]
    pub fn get<I>(&self, index: I) -> Option<&I::Output>
    where
        I: SliceIndex<Self>,
    {
        index.get(self)
    }

When i have these 4 functions

get() {}
get_mut()  {}
get_unchecked() {}
get_unchecked_mut() {}

which call data().get_xxx or data_mut().get_xxx

then I can use them in all other functions, instead of having to write the data() and data_mut() functions everywhere (for both single values as sub-slices)

Like so?

That looks a bit different.

I made this and it works with that 'static added to the generic T constraints. (the mut and unchecked versions as well).
I believe the 'static is needed because it is implemented in the trait itself.

Is that crazy or wrong?

Which brought me to the next question.
It would be really cool if this x,y, indexing was "traited"
Now I have separate get versions for

  • index: usize (or a range)
  • x: i32, y: i32 (y * width + x)
  • pt: Point (pt.y * width + pt.x)

There's nothing in the signature to imply that T outlives the lifetime on &self. You can do this:

    fn get<'s, I>(&'s self, idx: I) -> Option<&I::Output>
    where
        I: SliceIndex<[T]>,
        T: 's,

Here's your playground with that change and a bunch of bounds removed.

No.

Like, you want everything SliceIndex gets you, but also some more? That's doable, but trait overlap checks are probably going to add some limitations. Like, if you want a blanket implementation for the things that work with SliceIndex<[T]>, everything else that implements it will have to be a local type. Or, you have to write all those usize and range implementations yourself (via macro probably) instead of using a blanket implementation.

"Traited" playground.

1 Like

Ow, this looks more complicated for beginner-me.
I will have to study on that... Thank you!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.