闭包的使用

2019 年 11 月,Rust 1.39.0 中 async-await 的发布增加了它作为现代系统编程语言的吸引力,并使其更容易编写高度并发的服务。

现在要完全理解和理解 async-await 是如何产生的,如何使用它。我们看一下如何演进出来的。

新建项目

1
cargo new use_closuer39

打开 src/main.rs

1
2
3
let add = |x, y| x + y;
let result = add(3, 4);
println!("{}", result);

这是一个闭包。并且调用了它,会打印出结果是 7

如果闭包可以像普通函数一样被调用,那我们该如何使用呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fn receives_closure<F>(closure: F)
where
F: Fn(i32, i32) -> i32,
{
let result = closure(3, 5);
println!("闭包作为参数执行结果 => {}", result);
}

fn main() {
let add = |x, y| x + y;
receives_closure(add);
}

输出:
闭包作为参数执行结果 => 8

再看一下闭包捕获变量的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fn receives_closure2<F>(closure:F)
where
F:Fn(i32)->i32{
let result = closure(1);
println!("closure(1) => {}", result);
}

fn main() {
let y = 2;
receives_closure2(|x| x + y);

let y = 3;
receives_closure2(|x| x + y);
}
输出:
捕获变量的结果 => 3
捕获变量的结果 => 4

返回闭包

1
2
3
4
5
6
7
8
9
10
fn returns_closure() -> impl Fn(i32) -> i32 {
|x| x + 6
}

fn main() {
let closure = returns_closure();
println!("返回闭包 => {}", closure(1));
}
输出:
返回闭包 => 7

参数和返回值都有闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fn do1<F>(f: F, x: i32) -> impl Fn(i32) -> i32
where
F: Fn(i32, i32) -> i32{
move |y| f(x, y)
}

fn main() {

let add = |x, y| x + y;
let result = do1(add, 5);
println!("result(1) => {}", result(1));
}
输出
result(1) => 6

下面我们考虑一下是否可以做一个通用的

1
2
3
4
5
fn do2<F, X, Y, Z>(f: F, x: X) -> impl Fn(Y) -> Z
where
F: Fn(X, Y) -> Z{
move |y| f(x, y)
}

报错如下

1
2
3
4
5
6
7
8
9
10
11
12

error[E0507]: cannot move out of `x`, a captured variable in an `Fn` closure
--> src/main.rs:12:16
|
9 | fn do2<F, X, Y, Z>(f: F, x: X) -> impl Fn(Y) -> Z
| - captured outer variable
...
12 | move |y| f(x, y)
| -----------^----
| | |
| | move occurs because `x` has type `X`, which does not implement the `Copy` trait
| captured by this `Fn` closure

下面我们修改代码

1
2
3
4
5
6
7
8
9
10
11
12
13
fn do2<F, X, Y, Z>(f: F, x: X) -> impl Fn(Y) -> Z
where
F: Fn(X, Y) -> Z,
X: Copy{
move |y| f(x, y)
}
fn main(){
let add = |x, y| x + y;
let result = do2(add, 5);
println!("result(2) => {}", result(2));
}
输出
result(2) => 7

添加微信 公众号更多内容
wechat gzh