如何在启用价值突变的同时允许多个所有者?
How can I allow multiple owners while enabeling mutation of value?
我有一个 Enum,叫做 NodeType 允许 Network(Network) 或 Mesh(Mesh)[=59= 的值]。 Network和Mesh都是未知大小的结构体。网络实例包含节点结构的二维矢量,其中包含节点类型枚举,允许网络包含其他网络或网格结构。网格执行一些任意功能。
考虑以下 Network,它的 NodeType 向量大小为 1 x 3。内容为:[Mesh, Network0, Network1]。 first 元素(Mesh),做了一些事情并且无关紧要。 Second 元素 Network0 已创建,并在实例化时分配了一个 NodeType(Mesh)。与先前的包含 Mesh 的 Network 一样,这无关紧要。
第三个 元素 Network1 的创建方式与 Network0 相同,在创建时定义了 NodeType(Mesh)。但是,我们现在要向 Network1 的 NodeType Vector 添加一个新值。我的问题是我在为递归结构而不是递归循环的“根”分配值时遇到问题。在任何给定时间,一个子网络可能被多个父网络引用。我无法执行这些 NodeType 的深层复制,因为它可能(无限)大。
我看到的问题是节点包含 Arc。但是这些都是需要的,因为 Arc 允许很多 Networks 引用同一个 Struct 实例,而 RwLock 允许在线程时进行管理。
以下是使用的三个结构,以及实例化上述场景的主要结构:
节点
#[derive(Debug)]
pub(crate) struct Node {
guid: Uuid,
node: Arc<RwLock<NodeType>>,
}
impl Node {
pub(crate) fn new(subnet: NodeType) -> Node {
Node {
guid: Uuid::new_v4(),
node: Arc::new(RwLock::new(subnet))
}
}
pub(crate) fn node(self) -> Arc<RwLock<NodeType>> {
self.node.clone()
}
}
#[derive(Debug)]
pub(crate) enum NodeType {
Network(Network),
Mesh(Mesh),
}
网络
#[derive(Debug)]
pub(crate) struct Network {
guid: Uuid,
pub(crate) subnet: Vec<Vec<Node>>,
}
impl Network {
pub(crate) fn new(subnet: NodeType) -> Network {
Network {
guid: Uuid::new_v4(),
subnet: vec![vec![Node::new(subnet)]],
}
}
}
网格
#[derive(Debug, )]
pub(crate) struct Mesh {
guid: Uuid,
}
impl Mesh {
pub(crate) fn new() -> Mesh {
Mesh {
guid: Uuid::new_v4(),
}
}
}
主要
//Creates A NodeType(Mesh)
let a = NodeType::Mesh(Mesh::new());
//Assigns the NodeType(Mesh) as the Second Element
let mut agent0 = Network::new(a);
//Creates a NodeType(Network) that Contains a Single Mesh
let b = NodeType::Network(Network::new(NodeType::Mesh(Mesh::new())));
//Assigns A NodeType(Network) that Contains a NodeType(Mesh) as the first element.
agent0.subnet[0].push(Node::new(b));
//Creates a NodeType(Network), Containing A NodeType(Mesh)
let c = NodeType::Network(Network::new(NodeType::Mesh(Mesh::new())));
//Assigns A NodeType(Network) that Contains a NodeType(Mesh) as the third element.
agent0.subnet[0].push(Node::new(c));
//An Attempt to append an additional Mesh to the Third Element's NodeType Vector. (Not Currently Working)
let value = (*agent0.subnet[0][2].node()).get_mut();
if let NodeType::Network(mut content) = value {
// let d = NodeType::Mesh(Mesh::new());
// content.subnet[0].push(Arc::new(RwLock::new(NodeType::Mesh(Mesh::new()))))
}
收到的错误是:
let i = (*agent0.subnet[0][2].node()).get_mut();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Arc<async_std::sync::RwLock<NodeType>>`
我希望我的问题很清楚,我决定冒过度解释的风险而不是替代方案。
我认为这里的问题是你有一个 Arc<RwLock<NodeType>>
但当你只有一个不可变的引用时你试图 get_mut()
。正如 the documentation for RwLock
所说,
use std::sync::RwLock;
let lock = RwLock::new(5);
// many reader locks can be held at once
{
let r1 = lock.read().unwrap();
let r2 = lock.read().unwrap();
assert_eq!(*r1, 5);
assert_eq!(*r2, 5);
} // read locks are dropped at this point
// only one write lock may be held, however
{
let mut w = lock.write().unwrap();
*w += 1;
assert_eq!(*w, 6);
} // write lock is dropped here
所以你的代码缺少的是 Arc
只给你一个 non-mutable 引用你的 RwLock
这意味着你需要调用write
,然后 unrwap()
因为可能的结果,按照上面的示例获取对内部 NodeType
.
的可变引用
编辑:我认为这就是您在最后一节中想要的内容。虽然不能 100% 确定,因为它不会克隆您的 Arc
,但我认为这就是您 尝试 要做的事情:
//An Attempt to append an additional Mesh to the Third Element's NodeType Vector.
let mynode = &(agent0.subnet[0][2]);
let mut locker = mynode.node.write().unwrap();
if let NodeType::Network(content) = &mut *locker {
let my_mesh_nodetype = NodeType::Mesh(Mesh::new());
let my_fresh_node = Node::new(my_mesh_nodetype);
content.subnet[0].push(my_fresh_node);
}
根据您在代码中的评论,我认为这是正确的。
我有一个 Enum,叫做 NodeType 允许 Network(Network) 或 Mesh(Mesh)[=59= 的值]。 Network和Mesh都是未知大小的结构体。网络实例包含节点结构的二维矢量,其中包含节点类型枚举,允许网络包含其他网络或网格结构。网格执行一些任意功能。
考虑以下 Network,它的 NodeType 向量大小为 1 x 3。内容为:[Mesh, Network0, Network1]。 first 元素(Mesh),做了一些事情并且无关紧要。 Second 元素 Network0 已创建,并在实例化时分配了一个 NodeType(Mesh)。与先前的包含 Mesh 的 Network 一样,这无关紧要。
第三个 元素 Network1 的创建方式与 Network0 相同,在创建时定义了 NodeType(Mesh)。但是,我们现在要向 Network1 的 NodeType Vector 添加一个新值。我的问题是我在为递归结构而不是递归循环的“根”分配值时遇到问题。在任何给定时间,一个子网络可能被多个父网络引用。我无法执行这些 NodeType 的深层复制,因为它可能(无限)大。
我看到的问题是节点包含 Arc
以下是使用的三个结构,以及实例化上述场景的主要结构:
节点
#[derive(Debug)]
pub(crate) struct Node {
guid: Uuid,
node: Arc<RwLock<NodeType>>,
}
impl Node {
pub(crate) fn new(subnet: NodeType) -> Node {
Node {
guid: Uuid::new_v4(),
node: Arc::new(RwLock::new(subnet))
}
}
pub(crate) fn node(self) -> Arc<RwLock<NodeType>> {
self.node.clone()
}
}
#[derive(Debug)]
pub(crate) enum NodeType {
Network(Network),
Mesh(Mesh),
}
网络
#[derive(Debug)]
pub(crate) struct Network {
guid: Uuid,
pub(crate) subnet: Vec<Vec<Node>>,
}
impl Network {
pub(crate) fn new(subnet: NodeType) -> Network {
Network {
guid: Uuid::new_v4(),
subnet: vec![vec![Node::new(subnet)]],
}
}
}
网格
#[derive(Debug, )]
pub(crate) struct Mesh {
guid: Uuid,
}
impl Mesh {
pub(crate) fn new() -> Mesh {
Mesh {
guid: Uuid::new_v4(),
}
}
}
主要
//Creates A NodeType(Mesh)
let a = NodeType::Mesh(Mesh::new());
//Assigns the NodeType(Mesh) as the Second Element
let mut agent0 = Network::new(a);
//Creates a NodeType(Network) that Contains a Single Mesh
let b = NodeType::Network(Network::new(NodeType::Mesh(Mesh::new())));
//Assigns A NodeType(Network) that Contains a NodeType(Mesh) as the first element.
agent0.subnet[0].push(Node::new(b));
//Creates a NodeType(Network), Containing A NodeType(Mesh)
let c = NodeType::Network(Network::new(NodeType::Mesh(Mesh::new())));
//Assigns A NodeType(Network) that Contains a NodeType(Mesh) as the third element.
agent0.subnet[0].push(Node::new(c));
//An Attempt to append an additional Mesh to the Third Element's NodeType Vector. (Not Currently Working)
let value = (*agent0.subnet[0][2].node()).get_mut();
if let NodeType::Network(mut content) = value {
// let d = NodeType::Mesh(Mesh::new());
// content.subnet[0].push(Arc::new(RwLock::new(NodeType::Mesh(Mesh::new()))))
}
收到的错误是:
let i = (*agent0.subnet[0][2].node()).get_mut();
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
trait `DerefMut` is required to modify through a dereference, but it is not implemented for `Arc<async_std::sync::RwLock<NodeType>>`
我希望我的问题很清楚,我决定冒过度解释的风险而不是替代方案。
我认为这里的问题是你有一个 Arc<RwLock<NodeType>>
但当你只有一个不可变的引用时你试图 get_mut()
。正如 the documentation for RwLock
所说,
use std::sync::RwLock;
let lock = RwLock::new(5);
// many reader locks can be held at once
{
let r1 = lock.read().unwrap();
let r2 = lock.read().unwrap();
assert_eq!(*r1, 5);
assert_eq!(*r2, 5);
} // read locks are dropped at this point
// only one write lock may be held, however
{
let mut w = lock.write().unwrap();
*w += 1;
assert_eq!(*w, 6);
} // write lock is dropped here
所以你的代码缺少的是 Arc
只给你一个 non-mutable 引用你的 RwLock
这意味着你需要调用write
,然后 unrwap()
因为可能的结果,按照上面的示例获取对内部 NodeType
.
编辑:我认为这就是您在最后一节中想要的内容。虽然不能 100% 确定,因为它不会克隆您的 Arc
,但我认为这就是您 尝试 要做的事情:
//An Attempt to append an additional Mesh to the Third Element's NodeType Vector.
let mynode = &(agent0.subnet[0][2]);
let mut locker = mynode.node.write().unwrap();
if let NodeType::Network(content) = &mut *locker {
let my_mesh_nodetype = NodeType::Mesh(Mesh::new());
let my_fresh_node = Node::new(my_mesh_nodetype);
content.subnet[0].push(my_fresh_node);
}
根据您在代码中的评论,我认为这是正确的。