Warning
This post was published 113 days ago. The information described in this article may have changed.
The 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:
ss.foo()
would be the following. fn foo<'b>(&'b self) -> &'a [u8] where 'a:'b
ss
in fn split
is also required to be shorter than (fully spanned by) lifetime of both ss.raw
and return value of ss.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