Difference between `&self` and `&'a self` in `impl<'a>`
⚓ Rust 📅 2025-04-30 👤 surdeus 👁️ 10The following code can't compile. If replace ss.bar() to ss.foo() then it works as intended.
foo and bar only differs in receiver signature: &self and &'a self, which I initially supposed to be the same, as they are both in block of impl<'a> StrangeSplitter<'a>.
Here comes my suppose:
- My guess is the explicit version of
ss.foo()would be the following.
fn foo<'b>(&'b self) -> &'a [u8] where 'a:'b
- The "lifetime" of
ssinfn splitis also required to be shorter than (fully spanned by) lifetime of bothss.rawand return value ofss.foo().
Are 1. and 2. right?
The origin goal was to create a struct that accepts AsRef<[u8]>+'a and provides several slices valid even after the splitter gets dropped. In another word, a struct that owns, process and return references with lifetime beyond (lives longer than) the struct itself.
Any suggestion on better practice would be appreciated.
Test code: (Playground link here)
struct StrangeSplitter<'a> {
raw: &'a [u8],
}
impl<'a> StrangeSplitter<'a> {
fn foo(&self) -> &'a [u8] {
&self.raw[0..1]
}
fn bar(&'a self) -> &'a [u8] {
&self.raw[0..1]
}
}
fn split<'a>(raw: &'a [u8]) -> &'a [u8] {
let ss: StrangeSplitter<'a> = StrangeSplitter { raw };
// let a: &'a [u8] = ss.foo(); //This is okay
let a: &'a [u8] = ss.bar();
return a;
}
fn main() {
let raw: Vec<u8> = (0..8).collect();
let _ = split(&raw);
}
Compiler output:
error[E0597]: `ss` does not live long enough
--> src/main.rs:17:23
|
14 | fn split<'a>(raw: &'a [u8]) -> &'a [u8] {
| -- lifetime `'a` defined here
15 | let ss: StrangeSplitter<'a> = StrangeSplitter { raw };
| -- binding `ss` declared here
16 | // let a: &'a [u8] = ss.foo(); //This is okay
17 | let a: &'a [u8] = ss.bar();
| -------- ^^ borrowed value does not live long enough
| |
| type annotation requires that `ss` is borrowed for `'a`
18 | return a;
19 | }
| - `ss` dropped here while still borrowed
3 posts - 2 participants
🏷️ rust_feed