rust - Confusion with short lived lifetimed values that (on the surface) seem perfectly safe -
i'm having issue writing lexical analyzer in rust functions starting complain simple snippets otherwise appear harmless. starting become annoyance error messages not helping me pinpoint cause of problems , second time i'm reaching out on same program in same week (previous question here).
i have read book, i've understood it. i've watched/read numerous other articles , videos discussing lifetimes (both explicit , implicit) , part concept behind borrowing , moving make perfect sense, except in cases following:
my lexer has next
function who's purpose peek ahead @ next character , return it.
struct lexer<'a> { src: str::chars<'a>, buf: string, // ... not important } impl<'a> lexer<'a> { // ... not relevant // -> option<&char> caused it's own slew of problems // thought dereferencing character solve. fn next(&self) -> option<char> { let res = self.src.peekable().peek(); // convert option<&char> option<char> match res { some(ref c) => some(*c.clone()), none => none } } // ... not relevant }
the error i'm getting when doing is:
error: borrowed value not live long enough let res = self.src.peekable().peek(); ^~~~~~~~~~~~~~~~~~~
what understand error value peekable()
not living long enough, kind of makes sense me. i'm referencing return in line , calling function imagine returning pointer character @ next location iterator. naive solution was:
let mut peeker = self.src.peekable(); let res = peeker.peek();
if implement solution, see different error not make sense me:
error: cannot move out of borrowed content let mut peeker = self.src.peekable(); ^~~~
i'm not quite sure what's moving self
out of borrowed context here (i know it's borrowed &self
not sure what's moving out of borrowed context.
edit
i proposed question details wildly inaccurate. portion of post contained details has been updated actual facts - mixed 2 different situations had encountered similar error (similar me, @ least).
let's start second error.
as mentioned in comments, iterator::peekable
iterator adapter consumes iterator going make peekable. small reproduction:
let values = [1,2,3]; let mut iterator = values.iter(); iterator.peekable(); // consumes `iterator` iterator.next(); // not available anymore!
you can use iterator::by_ref
reference can consumed. note underlying iterator still advanced!
let values = [1,2,3]; let mut iterator = values.iter(); iterator.by_ref().peekable(); iterator.next();
in case, trying consume value out of borrowed struct (via &self
), has specific error cannot move out of borrowed content
.
let's @ original error:
let values = [1,2,3]; let next = values.iter().peekable().peek();
the problem here peek
returns reference. makes sense, don't know if item iterating on copy
able. however, reference has have somewhere live. place live peekable
iterator itself! peekable
allocates enough space store "next" element. when call peek
, advances underlying iterator, stores value, returns reference. check out function signature peek
see captured in code:
fn peek(&mut self) -> option<&i::item>
you can re-add lifetimes explicit:
fn peek<'a>(&'a mut self) -> option<&'a i::item>
in one-line version, create , destroy peekable
, there's value live, reference dies in same statement.
Comments
Post a Comment