Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing Index trait with lifetime

I want to overload the indexing operator for this struct :

struct Ram<'a> {
    ram: &'a mut [u8]
}

impl<'a> Ram<'a> {
  pub fn new( bytes: &mut[u8]) -> Ram {
    Ram {
        ram: bytes
    }
  }
}

... which basically is a "controller" over a byte array. I do it like that because I want to reuse it for byte arrays of different sizes. I understand that the lifetime is here to make sure the "ram" reference is valid throughout the execution. Here's my current index code:

use std::ops::{Index};
impl<'a> Index<usize> for Ram<'a> {
    type Output = u8;
    fn index(&self, i: usize) -> &'a u8 {
        &self.ram[i]
    }
}

This doesn't compile. Rust says there's an anonymous lifetime definition that conflicts with 'a at the index(...) definition : "error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements".

How am I supposed to implement this? Or am I just plain wrong with my assumptions about lifetimes? Thanks.

like image 310
wiz21 Avatar asked Sep 19 '25 05:09

wiz21


1 Answers

You didn't need to specify the lifetime of the returned reference (note -> &u8). Playground.

The error was because Index trait requires lifetime specifier of the object (&self) and returned value (&u8) to be the same (which is equivalent to require &self to live at least as long as the returned reference).

For simplicity of coding Rust allows to skip explicit specification of this lifetime, so leaving &self and &u8 is the same as to specify &'x self and &'x u8. You specified explicitly only one of the references' lifetime, thus confusing the compiler.

use std::ops::{Index};
impl<'a> Index<usize> for Ram<'a> {
    type Output = u8;
    fn index(&self, i: usize) -> &u8 {
        &self.ram[i]
    }
}

fn main() {
    let mut _ram = [0, 1, 2, 3]; 
    let ram_holder = Ram::new(&mut _ram);
    println!("{}", ram_holder[1]);
    // prints: 1
}
like image 130
Alexey Larionov Avatar answered Sep 22 '25 07:09

Alexey Larionov