use crate::List::{Cons, Nil};
use std::ops::Deref;
use std::rc::Rc;
use std::cell::RefCell;
#[derive(Debug)]enumList{Cons(Rc<RefCell<i32>>, Rc<List>),
Nil,}structMyBox<T>(T);
impl<T> MyBox<T>{
fn new(x: T)-> MyBox<T>{MyBox(x)}}
impl<T> Deref for MyBox<T>{
type Target = T;
fn deref(&self)->&T {&self.0}}
fn hello(name:&str){
println!("Hello, {}!", name);}structCustomSmartPointer{
data: String,}
impl Drop for CustomSmartPointer {
fn drop(&mut self){
println!("\nDropping CustomSmartPointer with data '{}'!", self.data);}}
fn main(){
let b = Box::new(5);
println!("b = {}", b);//let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
let x =5;
let y =&x;
assert_eq!(5, x);
assert_eq!(5,*y);
let x =5;
let y = Box::new(x);
assert_eq!(5, x);
assert_eq!(5,*y);
let x =5;
let y = MyBox::new(x);
assert_eq!(5, x);
assert_eq!(5,*y);
let m = MyBox::new(String::from("Rust"));hello(&m);
let c = CustomSmartPointer { data: String::from("my stuff")};
let d = CustomSmartPointer { data: String::from("other stuff")};
println!("CustomSmartPointers created.");
let c = CustomSmartPointer { data: String::from("some data")};
println!("CustomSmartPointer created");drop(c);
println!("CustomSmartPointer dropped before the end of main.");/*
let a = Rc::new(Cons(5,
Rc::new(Cons(10,
Rc::new(Nil)))));
let b = Cons(3, Rc::clone(&a));
let c = Cons(4, Rc::clone(&a));
let a = Rc::new(Cons(5, Rc::new(Cons(10, Rc::new(Nil)))));
println!("\ncount after creating a = {}", Rc::strong_count(&a));
let b = Cons(3, Rc::clone(&a));
println!("count after creating b = {}", Rc::strong_count(&a));
{
let c = Cons(4, Rc::clone(&a));
println!("count after creating c = {}", Rc::strong_count(&a));
}
println!("count after c goes out of scope = {}", Rc::strong_count(&a));
*/
let value = Rc::new(RefCell::new(5));
let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil)));
let b =Cons(Rc::new(RefCell::new(6)), Rc::clone(&a));
let c =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);}
lib.rs:
use std::cell::RefCell;
pub trait Messenger {
fn send(&self, msg:&str);}
pub structLimitTracker<'a, T: 'a + Messenger>{
messenger:&'a T,
value: usize,
max: usize,}
impl<'a, T> LimitTracker<'a, T>
where T: Messenger {
pub fn new(messenger:&T, max: usize)-> LimitTracker<T>{
LimitTracker {
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");}elseif percentage_of_max >=0.9{
self.messenger.send("Urgent warning: You've used up over 90% of your quota!");}elseif percentage_of_max >=0.75{
self.messenger.send("Warning: You've used up over 75% of your quota!");}}}
#[cfg(test)]
mod tests {
use super::*;
use std::cell::RefCell;}structMockMessenger{
sent_messages: RefCell<Vec<String>>,}
impl MockMessenger {
fn new()-> MockMessenger {
MockMessenger{ sent_messages: RefCell::new(vec![])}}}
impl Messenger for MockMessenger {
fn send(&self, message:&str){
self.sent_messages.borrow_mut().push(String::from("message"));
let mut one_borrow = self.sent_messages.borrow_mut();
let mut two_borrow = self.sent_messages.borrow_mut();
one_borrow.push(String::from(message));
two_borrow.push(String::from(message));}}
#[test]
fn it_sends_an_over_75_percent_warning_message(){
let mock_messenger = MockMessenger::new();
let mut limit_tracker = LimitTracker::new(&mock_messenger,100);
limit_tracker.set_value(80);
assert_eq!(mock_messenger.sent_messages.borrow().len(),1);}
circular-reference
main.rs:
use std::rc::Rc;
use std::cell::RefCell;
use std::rc::Weak;
use crate::List::{Cons, Nil};
#[derive(Debug)]enumList{Cons(i32, RefCell<Rc<List>>),
Nil,}
impl List {
fn tail(&self)-> Option<&RefCell<Rc<List>>>{
match self {Cons(_, item)=>Some(item),
Nil => None,}}}
#[derive(Debug)]structNode{
value: i32,
parent: RefCell<Weak<Node>>,
children: RefCell<Vec<Rc<Node>>>,}
fn main(){
let a = Rc::new(Cons(5, RefCell::new(Rc::new(Nil))));
println!("a initial rc count = {}", Rc::strong_count(&a));
println!("a next item = {:?}", a.tail());
let b = Rc::new(Cons(10, RefCell::new(Rc::clone(&a))));
println!("a 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 a = {}", Rc::strong_count(&a));//取消下面的注释行便可以观察到循环引用;它会造成栈的溢出。//println!("a next item = {:?}", a.tail());
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));{
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),);}