0

I have a function that will create one of several structs (all of which have a method of the same signature but have other, different, methods and traits); I would like to instance one of the structs in a function and return a reference to its method that can be called elsewhere.

// Pseudocode
type SizeGetter = fn()-> isize;

fn get_ref()-> &SizeGetter{
    let catch = Fish{weight: 12};
    &catch.get_weight()

    //Fish.get_weight() is used here but it may be any struct.method() -> isize
}

fn main() {
    let getit = get_ref();
    println!("{}", getit());
}

In the above my goal is to define catch.getweight() in a function, return a reference to that function and then call it later to get the size.

xeere
  • 23
  • 3

1 Answers1

0

That original attempt could not work because you cannot return a reference to something created in a function. In this case, returning something equivalent to a method to a locally created struct value requires the value to outlive the function's lifetime as well.

We can reference a method bar in a struct Foo with Foo::bar, but this one isn't bound to a receiver value. There is no syntax specifically for referencing a method call on a value. The solution instead is to create a closure that captures the value and calls the method.

let foo = Foo::new();
move || foo.bar()

Considering this Fish struct and implementation (adjusted to comply with naming conventions):

struct Fish {
    weight: usize,
}

impl Fish {
    fn weight(&self) -> usize {
        self.weight
    }
}

A function returning another self-sufficient function would be written like so:

fn fish_weight() -> impl Fn() -> usize {
    let r#catch = Fish { weight: 12 };
    move || r#catch.weight()
}

Using:

let get = fish_weight();
println!("Fish weight: {}", get());

Playground

E_net4
  • 27,810
  • 13
  • 101
  • 139
  • how would one go about using this recursively i.e. the function returns a function that returns a function that... and so on because i can't just write infinate arrows – xeere Apr 18 '20 at 22:09
  • The method itself can be recursive. Anything else is outside the scope of this question. – E_net4 Apr 19 '20 at 08:59