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

时间:2014-07-27 09:00:26

标签: 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);
}

打印:

a: foo
b: foo

然后,阅读some other question on 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];

编译器抱怨:

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

如果我尝试将行更改为:

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

它给了我这个错误:

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];
                                                                        ^~~~~~~~~~~~~

在这里,我很丢失。我该怎么做才能使它工作(如果可能的话)?

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

1 个答案:

答案 0 :(得分:6)

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

The Periodic Table of Rust Types列出

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

Closure with mutable environmentBare function type

一个闭包捕获它的环境,一个函数没有。

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

我们尚未(已经讨论过)有一个简短的语法来编写非捕获闭包,即。匿名函数。

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

有关关于Rust中的闭包和函数的有趣博客文章是Fn Types in Rust, Take 3Closures and the Borrow Checker