美文网首页
Rust 闭包初探

Rust 闭包初探

作者: Kernholz | 来源:发表于2022-03-07 20:51 被阅读0次

Rust 中的闭包

Rust 中的闭包(closure)是一类特殊的函数。与普通函数相比,闭包是匿名的(当然你可以把闭包赋值给一个变量);更重要的是,闭包可以从其被定义的作用域中捕获变量。

闭包的类型

在将闭包作为参数进行传递时,需要标注闭包的类型(实际上是 trait)。一共有三种类型:

  • Fn,表示可以多次调用,但不修改捕获的变量(捕获为不可变引用);
  • FnMut,表示可以多次调用,且可能会修改捕获的变量(捕获为可变引用);
  • FnOnce,表示只保证单次调用的可用性。

move 关键字

在闭包前加上 move 关键字,会将闭包的捕获方式从默认的引用捕获变为值捕获。

需要注意的是,使用了 move 的闭包依然可以实现 FnFnMut,这是因为闭包的类型取决于该闭包如何对捕获的变量进行操作,而不取决于它当初是如何捕获这些变量的。

fn main() {
    let mut a = 0;

    let mut fnmut = move || {
        a += 1;
        println!("Inner: {}", a);
    };

    fnmut();
    println!("Outer: {}", a);

    fnmut();
    println!("Outer: {}", a);
}

在上面的例子中,最后的输出是:

Inner: 1
Outer: 0
Inner: 2
Outer: 0

也即闭包 fnmut 内部的 a 和主函数 main() 中的 a 是两个独立的变量。

需要注意的是,这里实际上隐式地进行了一次 copy。如果捕获的量没有实现 Copy,则会进行 move,此时对应的量就不能再在外部环境中调用了。例如下面的例子:

fn main() {
    let data = vec![1, 2, 3];

    std::thread::spawn(move || {
        println!("captured {:?} by value", data)
    }).join().unwrap();

    println!("{:?}", data);
}

就会报错

error[E0382]: borrow of moved value: `data`
 --> src/main.rs:8:22
  |
2 |     let data = vec![1, 2, 3];
  |         ---- move occurs because `data` has type `Vec<i32>`, which does not implement the `Copy` trait
3 | 
4 |     std::thread::spawn(move || {
  |                        ------- value moved into closure here
5 |         println!("captured {:?} by value", data)
  |                                            ---- variable moved due to use in closure
...
8 |     println!("{:?}", data);
  |                      ^^^^ value borrowed here after move
  |
  = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

相关文章

  • Rust 闭包初探

    Rust 中的闭包 Rust 中的闭包(closure)是一类特殊的函数。与普通函数相比,闭包是匿名的(当然你可以...

  • rust 闭包与同步

    rust 闭包与同步 rust 闭包 rust闭包中主要包括两个部分,闭包参数和闭包环境变量。闭包函数和函数参数使...

  • Rust 闭包学习 (Fn/FnMut/FnOnce)

    学习 Rust 闭包记录 闭包作为参数 闭包作为结构体属性 异步使用闭包 主要就是加 Send trait,没加 ...

  • rust中的闭包

    Rust 的 闭包(closures)是可以保存进变量或作为参数传递给其他函数的匿名函数。可以在一个地方创建闭包,...

  • Rust编程语言-13-函数式编程(闭包和迭代器)

    Rust语言的设计吸收了许多其它语言的优秀设计,比如函数式编程和闭包 闭包closure 能捕获环境参数的匿名函数...

  • JavaScript闭包初探

    JavaScript的闭包 个人博客:Damonare的个人博客 首先声明,这是一篇面向小白的博客,不过也欢迎各位...

  • 2022-07-22

    1. rust 闭包 三种 Fn 的关系[https://course.rs/advance/functional...

  • RUST 学习日记 第20课 ——闭包

    RUST 学习日记 第20课 ——闭包 0x00 回顾与开篇 我们已经通过两节课介绍了Rust的函数使用方法,尤...

  • PHP闭包(Closure)初探

    匿名函数 提到闭包就不得不想起匿名函数,也叫闭包函数(closures),貌似PHP闭包实现主要就是靠它。声明一个...

  • swift初探之闭包

    闭包定义:一个函数和它捕获的变量、常量环境组合起来,称为闭包。(但是好多人会把闭包表达式简称闭包,但是其实是两回事...

网友评论

      本文标题:Rust 闭包初探

      本文链接:https://www.haomeiwen.com/subject/clynrrtx.html