Dear all,
I am relative new to Rust, coming from a long experience with garbage-collected languages (Java and Python).
I want to use a library some_library_i_cannot_modify
with a struct Middle
that keeps a reference to struct Inner
.
I would like to create my own struct MyOuter
that encapsulates the use of that library and exposes higher-level methods. This is where I get an error borrowed value does not live long enough
.
I understand that my method MyOuter::new()
cannot return a dangling reference to Inner
. I therefore try to extend life time of Inner
by passing the owned version of Inner
to my struct MyOuter
.
But now it complains "cannot move out of inner because it is borrowed"
.
I'm sure I could juggle with lifetimes somehow here, but I don't see how ...
Some help would be greatly appreciated.
Thanks in advance,
Vito
mod some_library_i_cannot_modify {
pub struct Inner {
pub inner_string: String,
}
pub struct Middle<'a> {
pub ref_inner: &'a Inner,
}
}
use crate::some_library_i_cannot_modify::{Inner, Middle};
struct MyOuter<'a> {
middle: Middle<'a>,
inner: Inner,
}
impl <'a> MyOuter<'a> {
fn new() -> Self {
let inner = Inner {
inner_string: String::from("inner"),
};
let middle: Middle<'a> = Middle {
ref_inner: &inner,
};
// Error happens here:
MyOuter { middle, inner }
}
fn do_something(&self) {
todo!("implement")
}
}
fn main() {
let outer = MyOuter::new();
outer.do_something();
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0597]: `inner` does not live long enough
--> src/main.rs:24:24
|
17 | impl <'a> MyOuter<'a> {
| -- lifetime `'a` defined here
18 | fn new() -> Self {
19 | let inner = Inner {
| ----- binding `inner` declared here
...
23 | let middle: Middle<'a> = Middle {
| ---------- type annotation requires that `inner` is borrowed for `'a`
24 | ref_inner: &inner,
| ^^^^^^ borrowed value does not live long enough
...
28 | }
| - `inner` dropped here while still borrowed
error[E0505]: cannot move out of `inner` because it is borrowed
--> src/main.rs:27:27
|
17 | impl <'a> MyOuter<'a> {
| -- lifetime `'a` defined here
18 | fn new() -> Self {
19 | let inner = Inner {
| ----- binding `inner` declared here
...
23 | let middle: Middle<'a> = Middle {
| ---------- type annotation requires that `inner` is borrowed for `'a`
24 | ref_inner: &inner,
| ------ borrow of `inner` occurs here
...
27 | MyOuter { middle, inner }
| ^^^^^ move out of `inner` occurs here
|
note: if `Inner` implemented `Clone`, you could clone the value
--> src/main.rs:2:5
|
2 | pub struct Inner {
| ^^^^^^^^^^^^^^^^ consider implementing `Clone` for this type
...
24 | ref_inner: &inner,
| ----- you could clone this value
Some errors have detailed explanations: E0505, E0597.
For more information about an error, try `rustc --explain E0505`.
error: could not compile `playground` (bin "playground") due to 2 previous errors