Why does passing a closure to function which accepts a function pointer not work?

后端 未结 2 1284
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-03 16:50

In the second edition of The Rust Programming Language (emphasis mine):

Function pointers implement all three of the closure traits (Fn,

相关标签:
2条回答
  • 2020-12-03 17:33

    A closure isn't a function.

    You can pass a function to a function expecting a closure, but there's no reason for the reverse to be true.

    If you want to be able to pass both closures and functions as argument, just prepare it for closures.

    For example:

    let a = String::from("abc");
    
    let x = || println!("x {}", a);
    
    fn y() {
        println!("y")
    }
    
    fn wrap(c: impl Fn()) {
        c()
    }
    
    wrap(x); // pass a closure
    wrap(y); // pass a function
    
    0 讨论(0)
  • 2020-12-03 17:41

    There are certain cases where you can pass a closure as a function pointer. This works:

    fn main() {
        let x = || {
            let a = String::from("abc");
            println!("{}", a);
        };
    
        fn wrap(c: fn()) {
            c()
        }
    
        wrap(x);
    }
    

    The important difference is that the closure is not allowed to capture anything from its environment. That means that we had to prevent the String from crossing the closure boundary.

    Any closure that doesn't capture environment can be trivially rewritten as a anonymous standalone function and then converted into a function pointer.

    Once you add an environment, it is no longer convertible and everything from the existing answer applies.

    Note that stating -> () is non-idiomatic as that's the default if nothing is specified.

    See also:

    • RFC 1558 - Closure to fn Coercion
    0 讨论(0)
提交回复
热议问题