Weak<T>(弱引用,打破循环引用,防止内存泄漏))
WeakT是一种非拥有性的引用。它不增加强引用计数只增加一个独立的“弱引用计数”。当所有强引用消失时数据会被立即释放无论还有多少个Weak引用存在。访问Weak指向的数据时必须先尝试将其“升级”upgrade为Rc或Arc。如果数据已被释放升级会失败返回None。主要方法Weak::new()创建一个空的弱引用。Rc::downgrade(rc)从强引用RcT创建弱引用WeakT。weak.upgrade() 尝试将WeakT升级为OptionRcT。如果数据已释放返回None。Rc::weak_count(rc)获取指向该数据的弱引用数量主要用于调试。5.1 双向链表 / 树结构父子关系在树结构中父节点持有子节点的强引用拥有权而子节点需要知道父节点是谁但不能拥有父节点否则形成环。因此子节点持有一个指向父节点的Weak引用。usestd::{cell::RefCell,rc::{Rc,Weak},};#[derive(Debug)]structNode{value:i32,parent:RefCellWeakNode,// 指向父节点的弱引用children:RefCellVecRcNode,// 指向子节点的强引用}fnmain(){// 创建一个父节点letnode1Rc::new(Node{value:1,parent:RefCell::new(Weak::new()),// 指向父节点的弱引用默认初始值为Nonechildren:RefCell::new(Vec::new()),// 指向子节点的强引用默认初始值为空Vec});// 创建一个子节点letnode2Rc::new(Node{value:2,parent:RefCell::new(Weak::new()),// 指向父节点的弱引用默认初始值为Nonechildren:RefCell::new(Vec::new()),// 指向子节点的强引用默认初始值为空Vec});*node2.parent.borrow_mut()Rc::downgrade(node1);// 将node2的父节点弱引用指向node1node1.children.borrow_mut().push(Rc::clone(node2));// 将node2的强引用添加到node1的子节点Vec中println!({:?},node1);println!({:?},node2);println!({:?},node2.parent.borrow().upgrade());// 将node2的父节点弱引用升级为强引用}5.2 图结构无向图/网状结构usestd::{cell::RefCell,rc::{Rc,Weak},};#[derive(Debug)]structVertex{// 顶点value:i32,neighbors:RefCellVecWeakVertex,// 邻居}fnmain(){// 创建一个顶点v1初始邻居为空Vecletv1Rc::new(Vertex{value:1,neighbors:RefCell::new(Vec::new()),// 邻居默认初始值为空Vec});// 创建一个顶点v2初始邻居为空Vecletv2Rc::new(Vertex{value:2,neighbors:RefCell::new(Vec::new()),// 邻居默认初始值为空Vec});// 创建一个顶点v3初始邻居为空Vecletv3Rc::new(Vertex{value:3,neighbors:RefCell::new(Vec::new()),// 邻居默认初始值为空Vec});v1.neighbors.borrow_mut().push(Rc::downgrade(v2));// 将v2添加到v1的邻居中v2.neighbors.borrow_mut().push(Rc::downgrade(v1));// 将v1添加到v2的邻居中v1.neighbors.borrow_mut().push(Rc::downgrade(v3));// 将v3添加到v1的邻居中println!({:?},v1);println!({:?},v2);println!({:?},v1.neighbors.borrow()// 获取v1的邻居的读取引用.iter()// 迭代v1的邻居.map(|w|w.upgrade())// 将v1的邻居的弱引用升级为强引用.collect::Vec_()// 收集升级后的强引用到Vec中);}