Last active
May 24, 2021 03:48
-
-
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)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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