rust - 存储对自身的引用
问题描述
我正在尝试在 Rust 中创建一个节点网络,我希望网络中的每个节点都知道每个其他连接的节点。我认为这可以用弱Rc
的来完成,如下所示:
use std::cell::Cell;
use std::cell::RefCell;
use std::rc::Rc;
use std::rc::Weak;
struct Node {
name: String,
known_nodes: Rc<RefCell<Vec<Weak<Node>>>>,
}
impl Node {
fn connect_to_network(&mut self) {
self.known_nodes
.borrow_mut()
.push(Rc::downgrade(&Rc::new(*self)));
}
}
fn main() {
let known_nodes = Rc::new(RefCell::new(Vec::new()));
let node_one = Node {
name: "node1",
known_nodes: known_nodes.copy(),
};
node_one.connect_to_network();
let node_two = Node {
name: "node2",
known_nodes: known_nodes.copy(),
};
node_two.connect_to_network();
}
然而,这会产生
无法移出借来的内容
在:
self.known_senders.borrow_mut().push(Rc::downgrade(&Rc::new(*self)));
因为*self
是移出中借来的内容&Rc::new(*self)
。关于每个节点如何跟踪网络中所有其他节点的任何想法?
解决方案
你应该将你的节点和你的网络分开,因为你的网络必须拥有你的节点的所有权才能创建一个Rc
(或者至少,它必须拥有一个已经创建的Rc
)。这是一个更好的设计,可以实现您想要的:
use std::rc::Rc;
use std::rc::Weak;
use std::cell::RefCell;
#[derive(Debug)]
struct Node {
name: String,
}
#[derive(Default, Debug)]
struct Network {
nodes: Rc<RefCell<Vec<Weak<Node>>>>,
}
impl Network {
fn add_node(&mut self, node: Node) -> Rc<Node> {
let node = Rc::new(node);
self.nodes.borrow_mut().push(Rc::downgrade(&node));
node
}
}
fn main() {
let mut network = Network::default();
let node_1 = Node { name: "node_1".into() };
let node_2 = Node { name: "node_2".into() };
let _node_1 = network.add_node(node_1);
let _node_2 = network.add_node(node_2);
}
如果要存储对 的引用self
,可以这样做:
use std::cell::RefCell;
use std::rc::Rc;
use std::rc::Weak;
type MutableNode = Rc<RefCell<Node>>;
type Network = Rc<RefCell<Vec<Weak<RefCell<Node>>>>>;
struct Node {
name: String,
others: Network,
}
impl Node {
fn new(name: String) -> MutableNode {
let node = Rc::new(RefCell::new(Node {
name,
others: Rc::new(RefCell::new(Vec::new())),
}));
{
let tmp = node.borrow();
tmp.others.borrow_mut().push(Rc::downgrade(&node));
}
node
}
fn add_node(&mut self, name: String) -> MutableNode {
let others = self.others.clone();
let node = Rc::new(RefCell::new(Node { name, others }));
self.others
.borrow_mut()
.push(Rc::downgrade(&node));
node
}
fn len(&self) -> usize {
self.others.borrow().len()
}
}
fn main() {
let node_0 = Node::new("node_0".into());
let node_1 = node_0.borrow_mut().add_node("node_1".into());
let node_2 = node_0.borrow_mut().add_node("node_2".into());
assert_eq!(node_0.borrow().len(), 3);
assert_eq!(node_1.borrow().len(), 3);
assert_eq!(node_2.borrow().len(), 3);
}
推荐阅读
- java - 在 indexOf 和 lastIndexOf 中使用正则表达式
- c# - 错误或 Azure DevOps 错误:TF402484 人事团队项目已被删除
- node.js - 使用 APIKey 访问 GoogleDrive 文件
- python - TypeError: 'str' object is not callable -- 对 API 的请求
- excel - Excel 创建的 Outlook 约会只通知我
- python - keras 回调列表生成错误:“元组”对象没有属性“set_model”
- javascript - 你如何从外部组件中使用反应函数组件内部的方法
- javafx - NullPointerException 将字符串从一个窗口传递到另一个窗口
- java - ExecutorService 提交方法返回的期货不保持提交顺序
- c++ - 使用 SetupAPI 获取有关设备的信息