std::marker::PhantomData and unused fields in structs

I did manage to get this compile in the end - does anyone else find that the process of asking the question well on a public forum organizes their thoughts well enough to solve the problem?

Anyway, the solution was to make Cacher::new supply some actual PhantomData which was a little weird but fair enough I guess. Then the new function didn't need additional parameters because they are "hardcoded" into the new method definition.

If you didn't have a new method you would still need to pass the data when building Cacher though... :frowning: Something like:

let cacher = Cacher {
    calculation: some_expensive_function,
    value: None,
    _phantom: PhantomData {},
};

which is ugly, but hey, the new method was a good idea anyway.

Cacher looks like this in my code now:

use std::marker::PhantomData;

pub struct Cacher<F,U,V>
    where F: Fn(U) -> V, V: Copy
{
    calculation: F,
    value: Option<V>,
    _phantom: PhantomData<U>,
}

impl<F,U,V> Cacher<F,U,V>
    where F: Fn(U) -> V, V: Copy
{
    pub fn new(calculation: F) -> Cacher<F,U,V> {
        Cacher {
            calculation,
            value: None,
            _phantom: PhantomData {},
        }
    }

    pub fn get(&mut self, arg: U) -> V {
        match self.value {
            Some(v) => v,
            None => {
                let v = (self.calculation)(arg);
                self.value = Some(v);
                v
            }
        }
    }
}

This seems like a hack to me, but from the RFC linked to in the SO answer maybe this will be prettier in the future? Maaaybe?

pub struct Cacher<F,U,V>
    where F: Fn(U) -> V, V: Copy
{
    calculation: F,
    value: Option<V>,
    phantom U
}