Search code examples
functionclosuresrust

Why the strong difference between closures and functions in Rust and how to work around it?


I just ran into a problem with how Rust handles closures.

Let's assume I'm a library author and have written this method

fn get(&mut self, handler: fn() -> &str){
    //do something with handler
}

Now if a user wants to call this method like this

let foo = "str";
server.get(|| -> &str { foo });

It won't work because Rust, according to it's documentation makes a strong difference between regular functions and closures.

Do I as a library author always have to make such methods accept closures instead of regular functions to not restrict library users too much?

Also it seems to me as if closures are the only way to write anonymous functions or am I mistaken?


Solution

  • Currently, fn() types can be automatically "promoted" to || types. (A closure with an empty environment, I suppose.) For example, this works:

    fn get(handler: || -> &str) -> &str {
        handler()
    }
    
    fn main() {
        fn handler_fn() -> &str { "handler_fn" }
        let handler_cl = || -> &str "handler_cl";
        println!("{}", get(handler_fn));
        println!("{}", get(handler_cl));
    }
    

    So if your library function get doesn't care whether handler is a closure or not, then it seems reasonable to just accept closures for maximum flexibility. But this isn't always possible. For example, if you wanted to execute handler in another task, then I believe it must be a fn or a proc type. (I'm not 100% certain here---I may be missing a detail.)

    With regard to anonymous functions, yes, a || or a proc closure are the only two ways to write anonymous functions.