鉴于以下防 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
}

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

推荐答案

2016-04-01 Update:

从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));
}

对closure参数的更改是因为closure are现在已解除绑定.

Original:

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

你要做的就是了结.以下工作:

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));
}

有几件事需要注意:

  1. 函数强制闭包,但事实并非如此.

  2. 由于borrow 规则的原因,您需要将f(val)的结果存储在一个临时文件中.简短版本:你需要对闭包的唯一访问才能调用它,而借阅判断器不够聪明,无法意识到这两个调用在其原始位置上是独立的.

  3. 闭包正在被unboxed closures个替换,所以这在future 会发生变化,但我们还没有完全做到.

Rust相关问答推荐

WebDriver等待三十四?(Rust Se)

什么是谓词的简短和简洁类型

重新导出proc宏导致未解决的extern crate错误""

Rust:跨多个线程使用hashmap Arc和rwlock

当rust中不存在文件或目录时,std::FS::File::Create().unwire()会抛出错误

在Rust中,在实现特征`Display`时,如何获取调用方指定的格式?

在跨平台应用程序中使用std::OS::Linux和std::OS::Windows

Gtk4-rs:将监视器作为gdk::monitor获取,而不是作为glib::对象获取

在本例中,为什么我不能一次多次borrow 可变变量?

作为1字节位掩码的布尔值 struct

为什么TcpListener的文件描述符和生成的TcpStream不同?

注释闭包参数强调使用高阶排定特征界限

从 Rust 中的 if/else 中的引用创建 MappedRwLockWriteGuard

在 Bevy 项目中为 TextureAtlas 精灵实施 NearestNeighbor 的正确方法是什么?

切片不能被 `usize` 索引?

为什么 i32 Box 类型可以在 Rust 中向下转换?

n 个范围的笛卡尔积

Rust 内联 asm 中的向量寄存器:不能将 `Simd` 类型的值用于内联汇编

如何将 while 循环内的用户输入添加到 Rust 中的向量?

基于名称是否存在的条件编译