Skip to content

Instantly share code, notes, and snippets.

@lovasoa
Created February 18, 2020 18:26
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 lovasoa/6b211caf00ecba27abd949ff81d28328 to your computer and use it in GitHub Desktop.
Save lovasoa/6b211caf00ecba27abd949ff81d28328 to your computer and use it in GitHub Desktop.
A macro for cached computed fields in rust. Generates a function that checks the cached value of a field, and computes it if it's is not present.
use std::fmt::Debug;
#[derive(Debug)]
struct S {
x: Option<u32>,
y: u32,
}
/// Generates a funtion named $field the returns the existing value for
/// $field in self if it's not None, and otherwise computes it in
/// self.$field (of type Option<$typ>)
macro_rules! cached_prop {
( $field:ident, $typ:ty, $compute_field:expr ) => {
fn $field(&mut self) -> $typ {
if let Some(value) = self.$field {value}
else {
let result = ($compute_field)(self);
self.$field = Some(result);
result
}
}
};
}
impl S {
fn compute_x(&self) -> u32 {
self.y * 2
}
cached_prop!{x, u32, S::compute_x}
}
fn main() {
let mut s = S{x:None, y:9};
dbg!(&s);
dbg!(&s.x());
dbg!(&s);
// This prints:
// s = S {x: None, y: 9,}
// s.x() = 18
// s = S {x: Some(18), y: 9,}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment