无法将闭包作为参数传递

Cannot pass closure as parameter

我现在正在学习 Rust,似乎我无法将闭包指定为函数参数。这是我拥有的:

fn foo(a: i32, f: |i32| -> i32) -> i32 {
    f(a)
}

fn main() {
    let bar = foo(5, |x| { x + 1 });
    println!("{}", bar);
}

我收到以下错误:

foo.rs:1:19: 1:20 error: expected type, found `|`
foo.rs:1 fn foo(a: i32, f: |i32| -> i32) -> i32 {

好的,所以它不喜欢闭包语法。这有点烦人,因为现在我必须这样写:

fn foo(a: i32, f: Box<Fn(i32) -> i32>) -> i32 {
    f(a)
}

fn main() {
    let bar = foo(5, Box::new(|x| { x + 1 }));
    println!("{}", bar);
}

所以这是怎么回事?我在几个不同的 places 中读到第一个示例是有效的,所以这个 "closure type parameter" 语法是否被删除了,或者我只是做错了什么?

Rust 从一开始就是以开放的方式开发的,从那时起这门语言已经发展了很多。您正在阅读的 Stack Overflow 文章 link 已有将近 1 年的历史,在 1.0 之前的 Rust 中,时间与一生一样长...(双关语)

最直接的答案是:请记住,很多文章、博客文章、SO 答案...都不再相关,因为语言发生了变化。如果您尝试了一个解决方案但它不起作用,只需找到更新的语法(就像您所做的那样!)并继续。

对于这个具体案例,this RFC 记录了从 |...| -> ...Fn/FnMut/FnOnce(...) -> ... 的变化。

顺便说一下,社区有一项计划来查找过时的文章并将其明确标记为已弃用,以避免出现此特定问题。不过,我找不到 link。

如果今天有人对这个问题感兴趣,这里是泛型的语法:

fn foo<F: Fn(i32) -> i32>(a: i32, f: F) -> i32 {
    f(a)
}

fn main() {
    let bar = foo(5, |x| { x + 1 });
    println!("{}", bar);
}

或者,使用特征对象:

fn foo(a: i32, f: Box<Fn(i32) -> i32>) -> i32 {
    f(a)
}

fn main() {
    let bar = foo(5, Box::new(|x| { x + 1 }));
    println!("{}", bar);
}

你应该更喜欢前者。