1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
use std::cmp::Eq;
use std::hash::Hash;
use std::collections::HashMap;
pub struct CachedFunction<TFunction, TInput, TReturn>
where
TFunction : Fn(TInput) -> TReturn,
TInput : Eq + Hash + Copy,
TReturn: Copy
{
calculation: TFunction,
values: HashMap<TInput, TReturn>
}
impl<TFunction, TInput, TReturn> CachedFunction<TFunction, TInput, TReturn>
where
TFunction : Fn(TInput) -> TReturn,
TInput : Eq + Hash + Copy,
TReturn: Copy
{
pub fn new(function: TFunction) -> CachedFunction<TFunction, TInput, TReturn> {
CachedFunction {
calculation: function,
values: HashMap::new()
}
}
pub fn value(&mut self, arg: TInput) -> TReturn {
if self.values.contains_key(&arg) {
self.values[&arg]
}
else {
let value = (self.calculation)(arg);
self.values.insert(arg, value);
value
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn cached_function_value_returns_expected_value() {
let input = 4;
let closure = |x: i32| x * x;
let expected = closure(input);
let mut function = CachedFunction::new(closure);
let actual = function.value(input);
assert_eq!(expected, actual);
}
#[test]
fn cached_function_returns_expected_value_on_subsequent_calls() {
let input = 4;
let mut function = CachedFunction::new(|x: i32| x * x);
let expected = function.value(input);
let actual = function.value(input);
assert_eq!(expected, actual);
}
}