我在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];
^~~~~~~~~~~~~
在这里,我很丢失。我该怎么做才能使它工作(如果可能的话)?
更一般地说,这两个语法之间用于指定此数组中函数类型的区别是什么?它似乎涉及生命周期,但我无法弄明白。
答案 0 :(得分:6)
Rust中的函数指针和闭包是完全不同的。
The Periodic Table of Rust Types列出
|T…| -> U
fn(T…) -> U
为Closure with mutable environment
和Bare function type
。
一个闭包捕获它的环境,一个函数没有。
无法在调用堆栈中向向上传递闭包,因为捕获的环境的生命周期无法指定/验证,函数不捕获任何内容,因此可以返回
我们尚未(已经讨论过)有一个简短的语法来编写非捕获闭包,即。匿名函数。
如您所见,这些之间存在显着的语义和句法差异,并且它们不可互换。
有关关于Rust中的闭包和函数的有趣博客文章是Fn Types in Rust, Take 3和Closures and the Borrow Checker。