函数数组的类型中`fn`和`||`之间的差异

Lev*_*ans 6 rust

我在Rust中做了一些简单的实验,涉及一系列函数,最后推出了这个工作代码:

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);
}
Run Code Online (Sandbox Code Playgroud)

打印:

a: foo
b: foo
Run Code Online (Sandbox Code Playgroud)

然后,在SO上阅读其他一些问题,我看到了|&String| -> String应该也能正常工作的语法,但是尝试这样:

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

static funcs: &'static [|&String| -> String] = &[fun1, fun2];
Run Code Online (Sandbox Code Playgroud)

编译器抱怨:

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

如果我尝试将行更改为:

static funcs: &'static [|&String|: 'static -> String] = &[fun1, fun2];
Run Code Online (Sandbox Code Playgroud)

它给了我这个错误:

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];
                                                                        ^~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

在这里,我很丢失.我能做些什么来使它工作(如果可能的话)?

更一般地说,这两个语法之间用于指定此数组中函数类型的区别是什么?它似乎涉及生命周期,但我无法弄明白.

til*_*ner 6

Rust中的函数指针和闭包是完全不同的.

锈类型的周期表列出了

|T…| -> U
fn(T…) -> U
Run Code Online (Sandbox Code Playgroud)

Closure with mutable environmentBare function type.

闭包捕获其环境,功能不捕获.

闭包不能在调用堆栈中向上传递,因为捕获的环境的生命周期无法指定/验证,函数不会捕获任何内容,因此可以返回.

我们不(一直存在讨论)有一个简短的语法来写非捕获关闭,即 匿名函数.

如您所见,这些之间存在显着的语义和句法差异,并且它们不可互换.

关于Rust中的闭包和函数的有趣博客文章是Rust,Take 3Closures以及Borrow Checker中的Fn类型.