gpt4 book ai didi

rust - 存储对自身的引用

转载 作者:行者123 更新时间:2023-11-29 08:25:02 25 4
gpt4 key购买 nike

我正在尝试在 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();
}

然而这产生了

cannot move out of borrowed content

在:

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);
}

关于rust - 存储对自身的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50677344/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com