设计思路
- 节点和边的定义:使用结构体分别定义节点和边,将其属性作为结构体字段。
- 图结构:
Graph
结构体包含节点和边的集合,节点之间通过引用相互连接。为确保生命周期安全,可使用Rc
(引用计数)和Weak
(弱引用)智能指针。Rc
用于强引用,保持节点存活,Weak
用于解决循环引用问题。
- 修改方法:在修改节点属性时,通过
Rc
获取可变引用,同时确保不违反借用规则。
代码实现
use std::rc::Rc;
use std::cell::RefCell;
use std::rc::Weak;
// 定义边的结构体
struct Edge {
// 边的属性
property: String,
}
// 定义节点的结构体
struct Node {
// 节点的属性
property: String,
// 连接的边
edges: Vec<Rc<Edge>>,
// 连接的其他节点
neighbors: Vec<Weak<Node>>,
}
// 定义图的结构体
struct Graph {
nodes: Vec<Rc<RefCell<Node>>>,
}
impl Graph {
// 创建新的图
fn new() -> Graph {
Graph { nodes: Vec::new() }
}
// 添加节点到图中
fn add_node(&mut self, property: String) -> Rc<RefCell<Node>> {
let new_node = Rc::new(RefCell::new(Node {
property,
edges: Vec::new(),
neighbors: Vec::new(),
}));
self.nodes.push(Rc::clone(&new_node));
new_node
}
// 添加边到图中
fn add_edge(&mut self, from: &Rc<RefCell<Node>>, to: &Rc<RefCell<Node>>, property: String) {
let edge = Rc::new(Edge { property });
from.borrow_mut().edges.push(Rc::clone(&edge));
to.borrow_mut().edges.push(Rc::clone(&edge));
from.borrow_mut().neighbors.push(Rc::downgrade(to));
to.borrow_mut().neighbors.push(Rc::downgrade(from));
}
// 安全地修改部分节点的属性
fn modify_node_property(&mut self, target_nodes: &[Rc<RefCell<Node>>], new_property: String) {
for node in target_nodes {
let mut node_ref = node.borrow_mut();
node_ref.property = new_property.clone();
}
}
}
避免借用检查错误
- 使用
RefCell
:RefCell
允许在运行时进行借用检查,从而在不违反借用规则的情况下实现内部可变性。
- 避免循环引用:使用
Weak
指针来避免节点之间的循环引用,确保内存安全。
- 可变借用管理:在
modify_node_property
方法中,通过borrow_mut
获取可变引用,确保同一时间只有一个可变引用,避免借用检查错误。