Skip to content

Instantly share code, notes, and snippets.

@guihao-liang
Last active May 24, 2021 03:48
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 guihao-liang/b815ad95afe5a3b3d0eedd3e1bef847a to your computer and use it in GitHub Desktop.
Save guihao-liang/b815ad95afe5a3b3d0eedd3e1bef847a to your computer and use it in GitHub Desktop.
self-referential function to implement state machine. [reference](https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html)
package main
import "fmt"
//
// https://commandcenter.blogspot.com/2014/01/self-referential-functions-and-design.html
//
// self-referential definition
// recursive definition
// it's like linked list
//
// type Node struct {
// next *Node
// }
//
type node func() node
func addOne(val, threshold int) node {
val += 1
fmt.Println(val)
return func() node {
if val >= threshold {
return nil
}
return addOne(val, threshold)
}
}
func main() {
// get the head, start from 0, end at 10
node := addOne(0, 10)
for node != nil {
// next node
node = node()
}
}
// https://users.rust-lang.org/t/self-referential-functions/60161?u=jarvi-izana
struct State {
val: i32,
end: i32,
}
pub struct StateFn(Box<dyn FnOnce(&mut State) -> Option<StateFn>>);
fn add_one() -> StateFn {
StateFn(Box::new(|state| {
println!("{}", state.val);
if state.val >= state.end {
return None;
}
state.val += 1;
Some(add_one())
}))
}
fn main() {
let mut state = State { val: 0, end: 10 };
let mut state_fn = add_one();
while let Some(next_state_fn) = state_fn.0(&mut state) {
state_fn = next_state_fn
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment