rust - Lifetime error for returned value of a function -


this simplified version of piece of code trying implement:

struct firststruct {     a:  i8, }  impl firststruct {      fn get(&self) -> option<&str>      {          some("aaa")      } }  pub struct secondstruct<'a> {     pub name:           option<&'a str>, }  impl<'a> secondstruct<'a> {     fn extract_string(obj: &/*'a*/ firststruct) -> option<&'a str>     {         obj.get() //this error happen     }      pub fn from_string() -> secondstruct<'a>     {         let obj = firststruct{a: 1};         secondstruct{             name:       secondstruct::extract_string(&obj),         }     } }  fn main() {     let g_def_res = secondstruct::from_string(); } 

this code throws following error :

test2.rs:23:13: 23:18 error: cannot infer appropriate lifetime autoref due conflicting requirements test2.rs:23         obj.get() //this error happen                         ^~~~~ test2.rs:21:5: 24:6 help: consider using explicit lifetime parameter shown: fn extract_string(obj: &'a firststruct) -> option<&'a str> test2.rs:21     fn extract_string(obj: &firststruct) -> option<&'a str> test2.rs:22     { test2.rs:23         obj.get() //this error happen test2.rs:24     } error: aborting due previous error 

applying proposed solution throw error :

test2.rs:30:55: 30:58 error: `obj` not live long enough test2.rs:30             name:       secondstruct::extract_string(&obj),                                                                   ^~~ test2.rs:27:5: 32:6 note: reference must valid lifetime 'a defined on block @ 27:4... test2.rs:27     { test2.rs:28         let obj = firststruct{a: 1}; test2.rs:29         secondstruct{ test2.rs:30             name:       secondstruct::extract_string(&obj), test2.rs:31         } test2.rs:32     } test2.rs:28:37: 32:6 note: ...but borrowed value valid block suffix following statement 0 @ 28:36 test2.rs:28         let obj = firststruct{a: 1}; test2.rs:29         secondstruct{ test2.rs:30             name:       secondstruct::extract_string(&obj), test2.rs:31         } test2.rs:32     } error: aborting due previous error 

to summarise:

how return value of firststruct::get must have lifetime of either [the return value of secondstruct::from_str | struct lifetime 'a]? think both refer same thing?

pub fn from_string() -> secondstruct<'a> {     let obj = firststruct { a: 1 };     secondstruct {         name: secondstruct::extract_string(&obj),     } } 

this code says "i return secondstruct lifetime 'a". caller of code gets determine length of lifetime 'a is. never want!

// lifetime elision means method equivalent // fn get<'a>(&'a self) -> option<&'a str>  fn get(&self) -> option<&str> {     some("aaa") } 

this code uses says string returned live long self lives.

put these 2 concepts together, , can understand error. variable obj defined live long function call active. however, trying return reference inner-workings of struct beyond call! actually, trying return any arbitrary lifetime caller decides! rust preventing shooting in foot, hooray rust!


so how fix problem? provided example code, easiest thing use 'static lifetime:

struct firststruct { a: i8 }  impl firststruct {     fn get(&self) -> option<&'static str> { some("aaa") } }  pub struct secondstruct<'a> { name: option<&'a str> }  impl<'a> secondstruct<'a> {     fn extract_string(obj: &firststruct) -> option<&'static str> { obj.get() }      pub fn from_string() -> secondstruct<'static> {         let obj = firststruct { a: 1 };         secondstruct { name: secondstruct::extract_string(&obj) }     } }  fn main() {     let g_def_res = secondstruct::from_string(); } 

but that's not want. next thing try embed firststruct inside secondstruct, , delegate it. option move &str string - string owns string data, , can transfer ownership first second.

whatever do, have ensure source of string data outlives function call from_string.


either return value of firststruct::get has been allocated on stack or has been allocated on heap.

it's trickier that. return value always on stack. is, option<&str> takes space on stack. &str may contain pointer allocated either on stack or heap, it's not known code. know pointed-at value guaranteed live lifetime of specific firststruct item.

you don't own string, can't transfer ownership around.

i can't move firststruct because library (rustc-serialize

i'm not sure mean. if have object, can embed object. fact comes crate doesn't come play. if have reference something, can still capture reference, object has live shorter period reference (so never becomes invalid).

unwrapping option, updating string , rewrapping in option lot of boilerplate.

have seen option::map? makes kind of thing succinct. combined from, can write short thing convert option<&str> option<string>:

// fn establish types, you'd use `.map` call in real code fn foo(a: option<&str>) -> option<string> {     a.map(from::from) } 

Comments

Popular posts from this blog

shopping cart - Page redirect not working PHP -

php - How to modify a menu to show sub-menus -

python - Installing PyDev in eclipse is failed -