Rc与RefCell
2023-04-18 15:37:34 时间
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,然后调用对象的方法,在改进之前直接调用对象方法会报错)。
}
相关文章
- 【技术种草】cdn+轻量服务器+hugo=让博客“云原生”一下
- CLB运维&运营最佳实践 ---访问日志大洞察
- vnc方式登陆服务器
- 轻松学排序算法:眼睛直观感受几种常用排序算法
- 十二个经典的大数据项目
- 为什么使用 CDN 内容分发网络?
- 大数据——大数据默认端口号列表
- Weld 1.1.5.Final,JSR-299 的框架
- JavaFX 2012:彻底开源
- 提升as3程序性能的十大要点
- 通过凸面几何学进行独立于边际的在线多类学习
- 利用行动影响的规律性和部分已知的模型进行离线强化学习
- ModelLight:基于模型的交通信号控制的元强化学习
- 浅谈Visual Source Safe项目分支
- 基于先验知识的递归卡尔曼滤波的代理人联合状态和输入估计
- 结合网络结构和非线性恢复来提高声誉评估的性能
- 最佳实践丨云开发CloudBase多环境管理实践
- TimeVAE:用于生成多变量时间序列的变异自动编码器
- 具有线性阈值激活的神经网络:结构和算法
- 内网渗透之横向移动 -- 从域外向域内进行密码喷洒攻击