如何在Rust中传递函数作为参数

Mar*_*ler 11 function parameter-passing rust

鉴于以下生锈程序:

fn call_twice<A>(val: A, f: fn(A) -> A) -> A {
    f(f(val))
}

fn main() {
    fn double(x: int) -> int {x + x};
    println!("Res is {}", call_twice(10i, double));
    // println!("Res is {}", call_twice(10i, (x: int) -> int {x + x}));
    // ^ this line will fail
}
Run Code Online (Sandbox Code Playgroud)

为什么我可以double作为函数传递,但不能内联?在没有定义函数的情况下实现相同行为的好方法是什么?

DK.*_*DK. 16

2016-04-01更新:

从Rust 1.0开始,代码应如下所示:

fn call_twice<A, F>(val: A, mut f: F) -> A
where F: FnMut(A) -> A {
    let tmp = f(val);
    f(tmp)
}

fn main() {
    fn double(x: i32) -> i32 {x + x};
    println!("Res is {}", call_twice(10, double));
    println!("Res is {}", call_twice(10, |x| x + x));
}
Run Code Online (Sandbox Code Playgroud)

到封闭参数的变化是因为封闭现在拆箱.

原版的:

就我所知,你不能像那样定义内联函数.

想要的是封闭.以下作品:

fn call_twice<A>(val: A, f: |A| -> A) -> A {
    let tmp = f(val);
    f(tmp)
}

fn main() {
    fn double(x: int) -> int {x + x};
    println!("Res is {}", call_twice(10i, double));
    println!("Res is {}", call_twice(10i, |x| x + x));
}
Run Code Online (Sandbox Code Playgroud)

有几点需要注意:

  1. 函数强制关闭,但事实恰恰相反.

  2. f(val)由于借用规则,您需要将结果存储在临时中.简短版本:您需要对闭包进行独特访问才能调用它,并且借用检查器不够聪明,无法实现两个调用在其原始位置是独立的.

  3. 闭包正在被无盒装封闭所取代,所以这将在未来发生变化,但我们还没有完全实现.

  • @SandeepDatta这个答案是2014年的答案; 即使在Rust 1.0中,此代码也无效.我已经更新了. (2认同)