Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Index trait to return a value that is not a reference

Tags:

indexing

rust

I have a simple struct that I would like to implement Index for, but as a newcomer to Rust I'm having a number of troubles with the borrow checker. My struct is pretty simple, I'd like to have it store a start and step value, then when indexed by a usize it should return start + idx * step:

pub struct MyStruct {
    pub start: f64,
    pub step: f64,
}

My intuition is that I'd simply be able to take the signature of Index and plug in my types:

impl Index<usize> for MyStruct {
    type Output = f64;

    fn index(&self, idx: usize) -> &f64 {
        self.start + (idx as f64) * self.step
    }
}

This gives the error mismatched types saying expected type &f64, found type f64. As someone who has yet to fully understand how Rust's type system works, I tried simply slapping & on the expression:

fn index(&self, idx: usize) -> &f64 {
    &(self.start + (idx as f64) * self.step)
}

This now tells me that the borrowed value does not live long enough, so maybe it needs a lifetime variable?

fn index<'a>(&self, idx: usize) -> &'a f64 {
    &(self.start + (idx as f64) * self.step)
}

The error is the same, but the note now gives lifetime 'a instead of lifetime #1, so I guess that's not necessary, but at this point I feel like I'm stuck. I'm confused that such a simple exercise for most languages has become so difficult to implement in Rust, since all I want to do is return a computation from a function that happens to be behind a reference. How should I go about implementing Index for a simple structure where the value is calculated on demand?

like image 597
bheklilr Avatar asked Aug 24 '16 02:08

bheklilr


1 Answers

The Index trait is meant to return a borrowed pointer to a member of self (e.g. an item in a Vec). The signature of the index method from the Index trait makes it impractical to implement it to have the behavior you described, as you'd have to store every value returned by index in self and ensure that the pointers remain valid until the MyStruct is dropped.

like image 195
Francis Gagné Avatar answered Nov 17 '22 16:11

Francis Gagné