20

I'm trying to make a struct that has a mutable function pointer. I have it setup so that the function pointer is initialized to a particular function, but rust doesn't recognize the pointer when i try to use it.

i get

hello.rs:24:14: 24:22 error: no method named `get_func` found for type `&Container` in the current scope
hello.rs:24         self.get_func(self, key)
                         ^~~~~~~~

here's my code

use std::collections::HashMap;

struct Container {
    field: HashMap<String, i32>,
    get_func: fn(&Container, &str) -> i32
}

fn regular_get(obj: &Container, key: &str) -> i32 {
    obj.field[key]
}

impl Container {
    fn new(val: HashMap<String, i32>) -> Container {
        Container {
            field: val,
            get_func: regular_get
        }
    }

    fn get(&self, key: &str) -> i32 {
        self.get_func(self, key)
    }
}

fn main() {
    let mut c:HashMap<String, i32> = HashMap::new();
    c.insert("dog".to_string(), 123);
    let s = Container::new(c);
    println!("{} {}", 123, s.get("dog"));
}
franklynd
  • 1,850
  • 3
  • 13
  • 11

1 Answers1

26

It looks like you just have two simple errors in your code. If you change this

fn get(&self, key: &str) -> Container
{
    self.get_func(self, key)
}

to this

fn get(&self, key: &str) -> i32
{
    (self.get_func)(self, key)
}

then it works. I don't know why the syntax self.get_func(self, key) doesn't work; it's probably just an oversight in the rust compiler.

Adrian
  • 14,931
  • 9
  • 45
  • 70
  • That first error is embarassing. The second one, doesn't make sense to me. I'm going to make an issue about it. – franklynd May 22 '16 at 04:01
  • 9
    It's simple -- the compiler thinks that you are trying to execute a method that is implemented on `Self`, but what you want is to access the field `get_func` and call it as a method instead. – Limeth Jul 20 '16 at 08:08
  • 1
    I used to bind the value to a new field and then call it, but this solution is more elegant. – Limeth Jul 20 '16 at 08:09
  • 1
    Many languages will parse `a.b()` as either "call method `b` on `a`" or "get function-like attribute `b` of `a` and call it". It sounds like rust will only use the former, probably as "safety through lack of ambiguity" feature? – Troy Daniels Jun 29 '21 at 15:17