Reputation: 1052
I have a little dummy parser, which uses the same &str during parsing:
struct Parser<'a>{
r: &'a str,
pos: usize
}
impl<'a, 'b: 'a> Parser<'a>{
fn new(s: &'b str)->Parser<'a>{
Parser{r: s, pos:0}
}
fn next(&'a self)->Parser<'a>{
Parser{r: self.r, pos: self.pos + 1}
}
fn nnext(&'a self)->Parser<'a>{
Parser{r: self.r, pos: self.pos + 2}
}
fn nnnext(&'a self)->Parser<'a>{
return self.next().nnext()
}
}
I would use it like this:
fn parse(s: &str){
let parser = Parser::new(s);
parser.nnnext();
}
I get the following error:
25 | return self.next().nnext()
| -----------^^^^^^^^
| |
| returns a value referencing data owned by the current function
| temporary value created here
The reference is guaranteed to outlive all Parser methods. How must is annotate lifetimes to express this? Especially, why does nnnext
not compile? It should be clear that the reference outlives self.next().nnext()
call.
Thank you very much for any assistance. Hendrik
Upvotes: 4
Views: 802
Reputation: 382092
By using &'a self
, you're conflating the lifetime of the parser with the lifetime of the string it refers to. There's no reason for that.
If you remove this constraint, there's no problem anymore:
struct Parser<'a>{
r: &'a str,
pos: usize
}
impl<'a> Parser<'a>{
fn new(s: &'a str)->Parser<'a>{
Parser{r: s, pos:0}
}
fn next(&self)->Parser<'a>{
Parser{r: self.r, pos: self.pos + 1}
}
fn nnext(&self)->Parser<'a>{
Parser{r: self.r, pos: self.pos + 2}
}
fn nnnext(&self)->Parser<'a>{
return self.next().nnext()
}
}
(I also removed the useless 'b
)
Upvotes: 4