basic_example/example/closures/mod.rs
1use std::{thread, cmp, hash};
2use std::time::Duration;
3use std::collections::HashMap;
4
5pub fn run(){
6 let simulated_user_specified_value = 10;
7 let simulated_random_number = 7;
8
9 generate_workout(
10 simulated_user_specified_value,
11 simulated_random_number
12 );
13}
14
15//fn simulated_expensive_calculation(intensity: u32) -> u32 {
16// println!("calculating slowly...");
17// thread::sleep(Duration::from_secs(2));
18// intensity
19//}
20
21fn generate_workout(intensity: u32, random_number: u32) {
22// let expensive_result =
23// simulated_expensive_calculation(intensity);
24
25// let expensive_closure = |num| {
26// println!("calculating slowly...");
27// thread::sleep(Duration::from_secs(2));
28// num
29// };
30
31 let mut expensive_closure = Cacher::new(|num|{
32 println!("calculating slowly...");
33 thread::sleep(Duration::from_secs(2));
34 num
35 });
36
37// if intensity < 25 {
38// println!("Today, do {} pushups!", expensive_closure(intensity));
39// println!("Next, do {} situps!", expensive_closure(intensity));
40// } else {
41// if random_number == 3 {
42// println!("Take a break today! Remember to stay hydrated!");
43// } else {
44// println!("Today, run for {} minutes!", expensive_closure(intensity));
45// }
46// }
47
48 if intensity < 25 {
49 println!("Today, do {} pushups!", expensive_closure.value(intensity));
50 println!("Next, do {} situps!", expensive_closure.value(intensity));
51 } else {
52 if random_number == 3 {
53 println!("Take a break today! Remember to stay hydrated!");
54 } else {
55 println!("Today, run for {} minutes!", expensive_closure.value(intensity));
56 }
57 }
58
59 let x = vec![1, 2, 3];
60 let equal_to_x = move |z| z == x;
61 let y = vec![1, 2, 3];
62 println!("{}", equal_to_x(y))
63}
64
65//所有的闭包都实现了 trait Fn、FnMut 或 FnOnce 中的一个
66// 闭包有一个 u32 的参数并返回一个 u32,这样所指定的 trait bound 就是 Fn(u32) -> u32
67
68// 定义一个 Cacher 结构体来在 calculation 中存放闭包并在 value 中存放 Option 值
69
70// 第一阶段:只针对单个数据u32有效
71//struct Cacher<T>
72// where T: Fn(u32) -> u32
73//{
74// calculation: T,
75// value: Option<u32>,
76//}
77
78//impl<T> Cacher<T> where T: Fn(u32) -> u32 {
79// fn new(calculation: T) -> Cacher<T> {
80// Cacher {calculation, value: None}
81// }
82//
83// fn value(&mut self, arg: u32) -> u32 {
84// match self.value {
85// Some(v) => v,
86// None => {
87// let v = (self.calculation)(arg);
88// self.value = Some(v);
89// v
90// },
91// }
92// }
93//}
94
95// 第二阶段:只针对所有u32类型参数有效
96struct Cacher<T>
97 where T: Fn(u32) -> u32
98{
99 calculation: T,
100 value: HashMap<u32, Option<u32>>,
101}
102
103impl<T> Cacher<T> where T: Fn(u32) -> u32 {
104 fn new(calculation: T) -> Cacher<T> {
105 Cacher {calculation, value: HashMap::new()}
106 }
107
108 fn value(&mut self, arg: u32) -> u32 {
109 let &opt = self.value.get(&arg).unwrap_or(&None);
110 match opt {
111 Some(v) => v,
112 None => {
113 let v = (self.calculation)(arg);
114 self.value.insert(arg, Some(v));
115 v
116 },
117 }
118 }
119}
120
121// 第三阶段:只针对所有参数类型参数有效 TODO: 实现有问题
122//struct Cacher<T, N>
123// where T: Fn(N) -> u32
124//{
125// calculation: T,
126// value: HashMap<N, Option<u32>>,
127//}
128//
129//impl<T, N> Cacher<T, N>
130// where
131// T: Fn(N) -> u32,
132// N: cmp::Eq + hash::Hash
133//{
134// fn new(calculation: T) -> Cacher<T, N> {
135// Cacher {calculation, value: HashMap::new()}
136// }
137//
138// fn value(&mut self, arg: N) -> u32 {
139// let &opt = self.value.get(&arg).unwrap_or(&None);
140// match opt {
141// Some(v) => v,
142// None => {
143// let v = (self.calculation)(arg);
144// self.value.insert(arg, Some(v));
145// v
146// },
147// }
148// }
149//}
150
151#[test]
152fn call_with_different_values() {
153 let mut c = Cacher::new(|a| a);
154
155 let v1 = c.value(1);
156 let v2 = c.value(2);
157
158 assert_eq!(v2, 2);
159}