Skip to content

Instantly share code, notes, and snippets.

@tstelzer
Created April 16, 2020 16:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tstelzer/e391093533abba1afd1e5efeea81c5ab to your computer and use it in GitHub Desktop.
Save tstelzer/e391093533abba1afd1e5efeea81c5ab to your computer and use it in GitHub Desktop.
Rust Closures Cache
struct Cacher<T>
where
T: Fn(u32) -> u32,
{
calculation: T,
value: HashMap<u32, u32>,
}
impl<T> Cacher<T>
where
T: Fn(u32) -> u32,
{
fn new(calculation: T) -> Cacher<T> {
Cacher {
calculation,
value: HashMap::new(),
}
}
fn value(&mut self, arg: u32) -> u32 {
// FIXME: Getting a clippy warning here, recommending
// `self.value.entry().or_insert` instead.
if self.value.contains_key(&arg) {
*self.value.get(&arg).unwrap()
} else {
self.value.insert(arg, (self.calculation)(arg));
*self.value.get(&arg).unwrap()
}
}
}
fn generate_workout(intensity: u32, random_number: u32) {
let mut expensive_resultexpensive_result = Cacher::new(|num| {
println!("calculating ...");
thread::sleep(Duration::from_secs(2));
num
});
if intensity < 25 {
println!(
"Today, do {} pushups!",
expensive_resultexpensive_result.value(intensity)
);
println!(
"Next, do {} situps!",
expensive_resultexpensive_result.value(intensity)
);
} else if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!(
"Today, run for {} minutes!",
expensive_resultexpensive_result.value(intensity)
);
}
}
fn main() {
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(simulated_user_specified_value, simulated_random_number);
}
struct Cacher<T>
where
T: Fn(u32) -> u32,
{
calculation: T,
value: HashMap<u32, u32>,
}
impl<T> Cacher<T>
where
T: Fn(u32) -> u32,
{
fn new(calculation: T) -> Cacher<T> {
Cacher {
calculation,
value: HashMap::new(),
}
}
fn value(&mut self, arg: u32) -> u32 {
let f = || (self.calculation)(arg);
// FIXME
// [rustc E0502] [E] cannot borrow `self.value` as mutable because it is also borrowed as
// immutable
//
// mutable borrow occurs here
*self.value.entry(arg).or_insert_with(f)
}
}
fn generate_workout(intensity: u32, random_number: u32) {
let mut expensive_resultexpensive_result = Cacher::new(|num| {
println!("calculating ...");
thread::sleep(Duration::from_secs(2));
num
});
if intensity < 25 {
println!(
"Today, do {} pushups!",
expensive_resultexpensive_result.value(intensity)
);
println!(
"Next, do {} situps!",
expensive_resultexpensive_result.value(intensity)
);
} else if random_number == 3 {
println!("Take a break today! Remember to stay hydrated!");
} else {
println!(
"Today, run for {} minutes!",
expensive_resultexpensive_result.value(intensity)
);
}
}
fn main() {
let simulated_user_specified_value = 10;
let simulated_random_number = 7;
generate_workout(simulated_user_specified_value, simulated_random_number);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment