Skip to content

Instantly share code, notes, and snippets.

@cryptowen
Last active September 18, 2019 17:00
Show Gist options
  • Save cryptowen/e49755b06d0ce82919a4c6fd736404c6 to your computer and use it in GitHub Desktop.
Save cryptowen/e49755b06d0ce82919a4c6fd736404c6 to your computer and use it in GitHub Desktop.
rust weak self reference
use std::cell::RefCell;
use std::rc::{Rc, Weak};
struct Bank {
vm: RefCell<Weak<VM>>,
}
impl Bank {
fn call(&self, addr: &str, method: &str) {
println!("bank: {} {}", addr, method);
if method == "a" {
self.a();
} else if method == "c" {
self.c();
}
}
fn a(&self) {
println!("a");
self.vm.borrow().upgrade().unwrap().call("dex", "b");
}
fn c(&self) {
println!("c");
}
}
struct Dex {
vm: RefCell<Weak<VM>>,
}
impl Dex {
fn call(&self, addr: &str, method: &str) {
println!("dex: {} {}", addr, method);
if method == "b" {
self.b();
}
}
fn b(&self) {
println!("b");
self.vm.borrow().upgrade().unwrap().call("bank", "c");
}
}
struct VM {
bank: Rc<Bank>,
dex: Rc<Dex>,
}
impl VM {
fn call(&self, addr: &str, method: &str) {
if addr == "bank" {
self.bank.call(addr, method);
} else if addr == "dex" {
self.dex.call(addr, method);
}
}
}
fn main() {
let bank = Rc::new(Bank {
vm: RefCell::new(Weak::new()),
});
let dex = Rc::new(Dex {
vm: RefCell::new(Weak::new()),
});
let vm = Rc::new(VM {
bank: Rc::clone(&bank),
dex: Rc::clone(&dex),
});
*bank.vm.borrow_mut() = Rc::downgrade(&vm);
*dex.vm.borrow_mut() = Rc::downgrade(&vm);
vm.call("bank", "a");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment