Reputation: 361
I'm learning Rust and trying to implement a cache-like struct to cache an object, but I'm stuck on an error.
src/main.rs
// The Result object to be cached
struct Result {
value: u32,
}
struct Cacher<'a, T>
where
T: Fn(u32) -> u32,
{
calc: T,
value: Option<&'a Result>,
}
impl<'a, T> Cacher<'a, T>
where
T: Fn(u32) -> u32,
{
fn new(calc: T) -> Cacher<'a, T> {
Cacher { calc, value: None }
}
fn get_value(&mut self, arg: u32) -> &Result {
match self.value {
Some(v) => v,
None => {
let v = (self.calc)(arg);
self.value = Some(&Result { value: v });
self.value.unwrap()
}
}
}
}
This results in the following error:
error[E0716]: temporary value dropped while borrowed
--> src/main.rs:28:40
|
15 | impl<'a, T> Cacher<'a, T>
| -- lifetime `'a` defined here
...
28 | self.value = Some(&Result { value: v });
| -------------------^^^^^^^^^^^^^^^^^^^-- temporary value is freed at the end of this statement
| | |
| | creates a temporary which is freed while still in use
| assignment requires that borrow lasts for `'a`
How would one fix this?
Upvotes: 3
Views: 4935
Reputation: 1637
You cannot return a reference to a value if no one owns this value.
Also when you are using your Cacher
you need to ensure that reference you've got by get_value
will not outlive Cacher
itself.
// The Result object to be cached
struct Result {
value: u32,
}
struct Cacher<T>
where
T: Fn(u32) -> u32,
{
calc: T,
value: Option<Result>, // We need to own the Result
}
impl<T> Cacher<T>
where
T: Fn(u32) -> u32,
{
fn new(calc: T) -> Cacher<T> {
Cacher { calc, value: None }
}
fn get_value(&mut self, arg: u32) -> &Result {
match self.value {
Some(ref v) => v, // destructuring value by reference to it
None => {
let v = (self.calc)(arg);
self.value = Some(Result { value: v });
self.value.as_ref().unwrap() // unwrapping value by reference to it
}
}
}
}
Upvotes: 2