13.3.0. 写在正文之前
Rust语言在设计过程中收到了很多语言的启发,而函数式编程对Rust产生了非常显著的影响。函数式编程通常包括通过将函数作为值传递给参数、从其他函数返回它们、将它们分配给变量以供以后执行等等。
在本章中,我们会讨论 Rust 的一些特性,这些特性与许多语言中通常称为函数式的特性相似:
- 闭包(本文)
- 迭代器
- 使用闭包和迭代器改进I/O项目
- 闭包和迭代器的性能
喜欢的话别忘了点赞、收藏加关注哦,对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
13.3.1. 回顾
还记得在 13.1 中的例子吗:
做一个程序,根据人的身体指数等因素生成自定义的运动计划。这个程序的算法逻辑并不是重点,重点是算法在计算过程中会花费几秒的时间。我们的目标是不让用户发生不必要的等待。具体来说就是仅在必要的时候才调用该算法,而且只调用一次。
当时我们修改代码为:
use std::thread;
use std::time::Duration;
fn main() {
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(
simulated_user_specified_value,
simulated_random_number,
);
}
fn generate_workout(intensity: u32, random_number: u32) {
let expensive_closure = |num| {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
};
if intensity < 25 {
println!("Today, do {} pushups!", expensive_closure(intensity));
println!("Next, do {} situps!", expensive_closure(intensity));
} else {
if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!("Today, run for {} minutes!", expensive_closure(intensity));
}
}
}
但是还存在一个问题:这么写没有解决闭包重复调用的问题。 在intensity
小于25的情况下调用了2次闭包。
对于这个问题,一个解决方案是把闭包的值赋给某个本地变量,让这个本地变量被输出语句重复调用。这么写问题的是会造成一些代码的重复。
所以这里更适合使用另一种解决方法:创建一个结构体,它持有闭包及其调用结果。也就是说,在第一次调用闭包后把结果存到闭包里,如果以后还要调用闭包就直接使用存在里面的结果。它的效果是只会在需要结果时才执行该包,而且可缓存结果。
这种模式通常叫 记忆化(memorization) 或 延迟计算(lazy evaluation)
13.3.2. 让结构体持有闭包
根据刚才的解决方法,目