src/main.rs
#[derive(Debug)]
enum List {
Cons(Rc<RefCell<i32>>, Rc<List>),
Nil,
}
use crate::List::{Cons, Nil};
use std::borrow::BorrowMut;
use std::cell::RefCell;
use std::rc::Rc;
use std::str::FromStr;
/*
fn main() {
// varlu是 Rc引用 指向 RefCell的地址; RefCell指向一个堆上的5
let value = Rc::new(RefCell::new(5));
// a 是一个Rc引用, 它指向一个Cons地址; Cons由一个指向value的Rc引用,和一个预留字段(下一个节点位置)组成;
let a = Rc::new(Cons(Rc::clone(&value), Rc::new(Nil)));
// b、c 是一个Cons, 它由一个Rc-RefCell和一个预留字段组成
let b = Cons(Rc::new(RefCell::new(3)), Rc::clone(&a));
let c = Cons(Rc::new(RefCell::new(4)), Rc::clone(&a));
let mut b1 = *value.borrow_mut() ;// 返回RefMut;
let mut b2 = *value.borrow_mut() ;// 返回RefMut;
println!("a after = {:?}", a);
println!("b after = {:?}", b);
println!("c after = {:?}", c);
}
*/
struct MyObj {
//1.
//sent_messages:Vec<String>,
//2.
//sent_messages: RefCell<i32>,
//3.
sent_messages: Rc<RefCell<Vec<String>>>,
//4.
//sent_messages: Rc<RefCell<i32>>,
}
impl MyObj {
fn new() -> MyObj {
MyObj {
//1.
// sent_messages:vec![],
//2.
// sent_messages: RefCell::new(5),
//3.
sent_messages: Rc::new(RefCell::new(vec![])),
//4.
//sent_messages: Rc::new(RefCell::new(5)),
}
}
}
fn main(){
let myObj = MyObj::new();
// 1. 不能编译, 违反多引用规则,提示对象未实现copy
// let mut d1 = myObj.sent_messages;
// let mut d2 = myObj.sent_messages;
// 2. 不能编译, 使用RefMut存储同样不能违反多引用规则。
// let mut d1 = myObj.sent_messages.borrow_mut();
// let mut d2 = myObj.sent_messages.borrow_mut();
// 错误的结论
// 3. 可以编译, 使用Rc包装RefMut, borrow过程相当于解引用Rc,获得不可变引用,BorrowMut相当于解引用RefCell,获得可变引用
// ------------------------------------------------------|--Rc--|----RefCell----|
//let d1=myObj.sent_messages.borrow();
//let mut md1 = myObj.sent_messages.borrow().borrow_mut();
//let mut md2 = myObj.sent_messages.borrow().borrow_mut();
//4. 能编译, 不能(*rc1).borrow_mut() 两次, 编译不通过, 提示借用多次
let rc1 = Rc::clone(&myObj.sent_messages);
let mut mt1 = (*rc1).borrow_mut();
mt1.push(String::from("message"));
// ** 小结 **
// Rc允许多个Rc指向同一个对象, 但是不允许移动和改变对象的值(值类型除外)
// RefCell允许在不可变引用上修改对象内部的值,但是不能移动所有权,以借用的方式修改(返回RefMut,然后调用对象的方法,在改进之前直接调用对象方法会报错)。
}
标签:mut,messages,let,Rc,RefCell,sent
From: https://www.cnblogs.com/heath/p/17215708.html