This question already has answers here:
Implement graph-like data structure in Rust
(3个答案)
3年前关闭。
我想对一个非常大的(节点数)图进行建模,该图由许多非常大的(内存方式)节点组成。由于节点是如此之大,所以我只想存储一次,然后将借用传递给它们,因此从概念上讲,是这样的:
当然,没有办法像这样构造
我想表达的是各种各样的竞技场,这使我可以分配很多
在语义上可以在Rust中表达吗?
(3个答案)
3年前关闭。
我想对一个非常大的(节点数)图进行建模,该图由许多非常大的(内存方式)节点组成。由于节点是如此之大,所以我只想存储一次,然后将借用传递给它们,因此从概念上讲,是这样的:
struct Graph<'a> {
nodes: Vec<Node<'a>>,
}
struct Node<'a> {
edges: HashMap<String, &'a Node>,
// ...lots of other data...
}
当然,没有办法像这样构造
Graph
,因为(a)借用元素时Vec
不允许我添加新节点,并且(b)我不能告诉rustc nodes
向量将用于终身'a
。我也不能使用Rc
之类的东西,因为该图具有循环。我想表达的是各种各样的竞技场,这使我可以分配很多
Node
,只要竞技场存在,就向它们进行不可变的借用,并使用生命周期检查来确保没有剩余的Node
引用竞技场被取消分配时退出。就像是:struct Graph<'a> {
nodes: Arena<'a, Node<'a>>,
}
struct Node<'a> {
edges: HashMap<String, &'a Node>,
}
impl<'a, A> Arena<'a, A> {
fn own(&self, a: A) -> &'a A {
// magic
}
}
impl<'a, A> Drop for Arena<'a, A> {
fn drop(&'a mut self) {
// magic
}
}
在语义上可以在Rust中表达吗?
最佳答案
一个简单的解决方法是使用typed-arena条板箱。它包含带有Arena
方法的fn alloc(&self, T) -> &mut T
类型。
另一个简单的解决方案是使用索引而不是引用(并且永远不要从Vec
中删除,因为这会使索引无效)。在64位平台上,使用32位索引可能会减少一些字节。
但是,两种解决方案都无法删除节点。您可能会停止引用它们,但它们仍将保留在内存中,因此,将它们用于动态图(节点来回移动)需要更多的工作。在这种情况下,我的建议是从新的竞技场定期创建图的新克隆(不复制未使用的节点),这类似于使用移动垃圾收集器(如果自动化程度较低)。
10-06 03:47