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 copyable. 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

Popular posts from this blog

java - Custom OutputStreamAppender not run: LOGBACK: No context given for <MYAPPENDER> -

java - UML - How would you draw a try catch in a sequence diagram? -

c++ - No viable overloaded operator for references a map -