Differences between `fn` and `||` in type for an array of functions

|▌冷眼眸甩不掉的悲伤 提交于 2021-02-05 02:52:10

问题


I was doing some simple experiments in Rust, involving an array of functions, and finally came out with this working code:

fn fun1(arg: &String) -> String {
    let prefix = String::from_str("a: ");
    prefix.add(arg)
}

fn fun2(arg: &String) -> String {
    let prefix = String::from_str("b: ");
    prefix.add(arg)
}

fn doall(arg: &String, funcs_vec: &[fn(&String) -> String]) {
    for f in funcs_vec.iter() {
        println!("{}", (*f)(arg));
    }
}

static funcs: &'static [fn(&String) -> String] = &[fun1, fun2];

fn main() {
    doall(&String::from_str("foo"), funcs);
}

which prints:

a: foo
b: foo

Then, reading some other question on SO, I saw the syntax |&String| -> String that should work as well, but trying it like this :

fn doall(arg: &String, funcs_vec: &[|&String| -> String]) {
    for f in funcs_vec.iter() {
        println!("{}", (*f)(arg));
    }
}

static funcs: &'static [|&String| -> String] = &[fun1, fun2];

Compiler complains with:

funcarray.rs:17:25: 17:45 error: missing lifetime specifier
funcarray.rs:17 static funcs: &'static [|& String| -> String] = &[fun1, fun2];
                                        ^~~~~~~~~~~~~~~~~~~~

If I try to change the line to this:

static funcs: &'static [|&String|: 'static -> String] = &[fun1, fun2];

it gives me this error :

funcarray.rs:17:57: 17:70 error: mismatched types:
    expected `&'static ['static |&collections::string::String| -> collections::string::String:'static]`
    but found `&'static [fn(&collections::string::String) -> collections::string::String]`
(expected fn but found extern fn)
funcarray.rs:17 static funcs: &'static [|&String|: 'static -> String] = &[fun1, fun2];
                                                                        ^~~~~~~~~~~~~

And here I'm pretty lost. What can I do to make it work (if it is possible) ?

And more generally, what are the differences between these two syntaxes for specifying the type of the functions in this array ? It seems to involve lifetimes, but I can't figure it out.


回答1:


A function pointer and a closure are quite different in Rust.

The Periodic Table of Rust Types lists

|T…| -> U
fn(T…) -> U

as Closure with mutable environment and Bare function type.

A closure captures its environment, a function does not.

A closure cannot be passed upwards in the call stack, because the lifetime of the captured environment cannot be specified/validated, a functions does not capture anything and can therefore be returned.

We do not yet (there has been discussion) have a short syntax to write non-capturing closures, ie. anonymous functions.

As you see, there is a significant semantic and syntactic difference between these and they're not interchangeable.

Interesting blog articles to read about closures and functions in Rust are Fn Types in Rust, Take 3 and Closures and the Borrow Checker.



来源:https://stackoverflow.com/questions/24979454/differences-between-fn-and-in-type-for-an-array-of-functions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!