Returning reference to generic type with generic Fn trait/value

257 views Asked by At

I'm just starting to learn Rust and working through the Rust book. One of the chapters leads through a few examples and ends with a "try to make this generic" type of suggested exercises. I've been totally banging my head on this. The semi-generic type you start with is this:

struct Cacher<T>
    where T: Fn(i32) -> i32
{
    value: Option<i32>,
    // leaving out rest for brevity

Then I get to work converting this so that the Fn trait is also generic, which also directly impacts the "value." So here is what I came up with:

struct Cacher<T, U>
    where T: Fn(U) -> U
{
    calculation: T,
    value: Option<U>,
}

impl<T, U> Cacher<T, U>
    where T: Fn(U) -> U
{
    fn new(calculation: T) -> Cacher<T, U> {
        Cacher {
            calculation,
            value: Option::None,
        }
    }

    fn value(&mut self, arg: U) -> &U {
        match self.value {
            Some(ref v) => v,
            None => {
              let v = (self.calculation)(arg);
              self.value = Some(v);
              // problem is returning reference to value that was in
              // v which is now moved, and unwrap doesn't seem to work...
            },
        }
    }
}

All my issues are in the fn value getter. I'm not sure if I'm close or I simply went down the completely wrong path. So where am I going off the rails?

1

There are 1 answers

1
swizard On BEST ANSWER

and unwrap doesn't seem to work...

The problem is that unwrap takes it's argument by value, so it becomes moved.

Something like self.value.as_ref().unwrap() should do the trick.