Christoph
Christoph

Reputation: 27975

Why can't I call my function?

struct Floor{
    requestHandler: Option<RequestHandler>
}

struct RequestHandler{
    uri: StrBuf,
    handler: fn() -> StrBuf
}

impl Floor {

    fn do_something(&self){
        //(&self.requestHandler.unwrap().handler)();
        //expected function but found `&fn() -> std::strbuf::StrBuf`

        //(*(&self.requestHandler.unwrap().handler))();
        //cannot move out of dereference of `&`-pointer

        //(self.requestHandler.unwrap().handler)();
        //cannot move out of dereference of `&`-pointer
    }
}

fn main() {

    let foo = Floor {
        requestHandler: None
    };

    foo.do_something();
}

In do_something I try to get to my fn which is stored on the handler property of my RequestHandler struct.

Whatever I try, I just seem to be unable to call it (see the compiler messages beneath my failed attempts in the code).

Upvotes: 1

Views: 300

Answers (1)

huon
huon

Reputation: 102016

The problem is the signature of Option.unwrap:

impl Option<T> {
    fn unwrap(self) -> T { ... }
}

That is, it is taking the Option by value. RequestHandler has to move when used by value, since StrBuf moves (specifically StrBuf isn't Copy which forces RequestHandler to also not be Copy).

The correct way to handle this is to call Option.as_ref:

impl Option<T> {
    fn unwrap<'r>(&'r self) -> Option<&'r T> { ... }
}

That is, it takes a reference to an Option and gives you an Option containing a reference to what the original Option contained, this means that .unwrap will then give you that reference, pointing to the RequestHandler inside self, to handle as you wish.

(self.requesthandler.as_ref().unwrap().handler)()

Upvotes: 2

Related Questions