use std::cell::RefCell;
use std::ops::Deref;
use std::rc::{Rc, Weak};
fn main() {
weak_smart_pointer();
circulate_quote();
rc_and_ref_cell();
refcell_smart_pointer();
box_smart_pointer();
pointer();
}
fn weak_smart_pointer() {
let leaf = Rc::new(Node {
value: 3,
parent: RefCell::new(Weak::new()),
children: RefCell::new(vec![]),
});
println!("leaf strong = {},weak = {}", Rc::strong_count(&leaf), Rc::weak_count(&leaf)); println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
{
let branch = Rc::new(Node {
value: 5,
parent: RefCell::new(Weak::new()),
children: RefCell::new(vec![Rc::clone(&leaf)]),
});
*leaf.parent.borrow_mut() = Rc::downgrade(&branch); println!("branch strong = {},weak = {}", Rc::strong_count(&branch), Rc::weak_count(&branch)); println!("leaf strong = {},weak = {}", Rc::strong_count(&leaf), Rc::weak_count(&leaf)); println!("leaf parent = {:?}", leaf.parent.borrow().upgrade()); }
println!("leaf strong = {},weak = {}", Rc::strong_count(&leaf), Rc::weak_count(&leaf)); println!("leaf parent = {:?}", leaf.parent.borrow().upgrade());
#[derive(Debug)]
struct Node {
value: i32,
parent: RefCell<Weak<Node>>,
children: RefCell<Vec<Rc<Node>>>,
}
}
fn circulate_quote() {
let a = Rc::new(List::Cons(5, RefCell::new(Rc::new(List::Nil))));
println!("a initial rc count = {}", Rc::strong_count(&a));
println!("a next item = {:?}", a.tail());
let b = Rc::new(List::Cons(10, RefCell::new(Rc::clone(&a))));
println!("a initial rc count after b creation = {}", Rc::strong_count(&a));
println!("b initial rc count = {}", Rc::strong_count(&b));
println!("b next item = {:?}", b.tail());
if let Some(link) = a.tail() {
*link.borrow_mut() = Rc::clone(&b);
}
println!("b rc count after changing a = {}", Rc::strong_count(&b));
println!("a rc count after changing b = {}", Rc::strong_count(&a));
#[derive(Debug)]
enum List {
Cons(i32, RefCell<Rc<List>>),
Nil,
}
impl List {
fn tail(&self) -> Option<&RefCell<Rc<List>>> {
match self {
List::Cons(_, item) => Some(item),
List::Nil => None
}
}
}
}
fn rc_and_ref_cell() {
let value = Rc::new(RefCell::new(5));
let a = Rc::new(List::Cons(Rc::clone(&value), Rc::new(List::Nil)));
let b = List::Cons(Rc::new(RefCell::new(6)), Rc::clone(&a));
let c = List::Cons(Rc::new(RefCell::new(10)), Rc::clone(&a));
*value.borrow_mut() += 10;
println!("a after = {:?}", a);
println!("b after = {:?}", b);
println!("c after = {:?}", c);
#[derive(Debug)]
enum List {
Cons(Rc<RefCell<i32>>, Rc<List>),
Nil,
}
}
fn refcell_smart_pointer() {
let m = MockMessenger::new();
let mut l = LimitTracker::new(&m, 100);
l.set_value(80);
impl Messenger for MockMessenger {
fn send(&self, msg: &str) {
let mut ref_mut = self.sent_messages.borrow_mut();
ref_mut.push(String::from(msg)); println!("sent_messages_len: {}", ref_mut.len());
}
}
struct MockMessenger {
sent_messages: RefCell<Vec<String>>,
}
impl MockMessenger {
fn new() -> Self {
Self {
sent_messages: RefCell::new(vec![])
}
}
}
pub trait Messenger {
fn send(&self, msg: &str);
}
pub struct LimitTracker<'a, T: Messenger> {
messenger: &'a T,
value: usize,
max: usize,
}
impl<'a, T> LimitTracker<'a, T> where T: Messenger {
pub fn new(messenger: &'a T, max: usize) -> Self {
Self {
messenger,
value: 0,
max,
}
}
pub fn set_value(&mut self, value: usize) {
self.value = value;
let percentage_of_max = self.value as f64 / self.max as f64;
if percentage_of_max >= 1.0 {
self.messenger.send("Error: You are over your quota!");
} else if percentage_of_max >= 0.9 {
self.messenger.send("Urgent warning: You've used up over 90% of your quota!");
} else if percentage_of_max >= 0.75 {
self.messenger.send("Warning: You've used up over 75% of your quota!");
}
}
}
}
fn rc_smart_pointer() {
use crate::RcList::{Cons, Nil};
let rc_list = Rc::new(Cons(2, Rc::new(Cons(3, Rc::new(Nil)))));
let a = Cons(1, Rc::clone(&rc_list)); println!("var a Rc::clone(&rc_list) Rc::strong_count(&rc_list):{}", Rc::strong_count(&rc_list)); {
let b = Cons(0, Rc::clone(&rc_list)); println!("var b Rc::clone(&rc_list) Rc::strong_count(&rc_list):{}", Rc::strong_count(&rc_list)); } println!("Rc::clone(&rc_list) Rc::strong_count(&rc_list):{}", Rc::strong_count(&rc_list));}
fn box_smart_pointer() {
use crate::List::{Cons, Nil};
let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
println!("box_smart_pointer: {:#?}", list);
let x = 5;
let y = MyBox::new(x);
println!("box_smart_pointer: {}", x == *y);
let my_box_string = MyBox::new(String::from("解引用转换"));
deref_coercion(&my_box_string);
println!("提前释放执行前");
drop(y);
println!("提前释放执行完毕");
}
fn deref_coercion(str: &str) {
println!("deref_coercion: {}", str);
}
fn pointer() {
let x = 5;
let y = &x;
println!("pointer: {}", x == *y);
}
#[derive(Debug)]
enum List<T> {
Cons(T, Box<List<T>>),
Nil,
}
#[derive(Debug)]
enum RcList<T> {
Cons(T, Rc<RcList<T>>),
Nil,
}
struct MyBox<T> (T);
impl<T> MyBox<T> {
fn new(t: T) -> Self {
Self(t)
}
}
impl<T> Deref for MyBox<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl<T> Drop for MyBox<T> {
fn drop(&mut self) {
println!("MyBox离开作用域自动调用drop()");
}
}