Graph 结构中的可变向量

Graph 结构中的可变向量,graph,rust,Graph,Rust,我正在尝试一种在Rust中工作的图聚类算法。代码的一部分是带有邻接列表表示的WeightedGraph数据结构。核心将如下所示(用Python显示以明确我要做的事情): 类边(对象): 定义初始值(自身、目标、重量): self.target=目标 自重 类权重图(对象): 定义初始大小(自身、初始大小): self.adjancy_list=[[]表示范围内的i(初始_大小)] self.size=初始尺寸 self.edge\u计数=0 def添加_边缘(自身、源、目标、重量): self.

我正在尝试一种在Rust中工作的图聚类算法。代码的一部分是带有邻接列表表示的
WeightedGraph
数据结构。核心将如下所示(用Python显示以明确我要做的事情):

类边(对象):
定义初始值(自身、目标、重量):
self.target=目标
自重
类权重图(对象):
定义初始大小(自身、初始大小):
self.adjancy_list=[[]表示范围内的i(初始_大小)]
self.size=初始尺寸
self.edge\u计数=0
def添加_边缘(自身、源、目标、重量):
self.adjacence_list[source].append(边(目标,权重))
self.edge_计数+=1
因此,邻接列表包含一个
n
数组的数组:图中的每个节点对应一个数组。内部数组保存该节点的相邻节点,表示为
目标
节点编号和双
权重

我试图将整件事转化为锈迹,结果如下:

struct Edge {
    target: uint,
    weight: f64
}

struct WeightedGraph {
    adjacency_list: ~Vec<~Vec<Edge>>,
    size: uint,
    edge_count: int
}

impl WeightedGraph {
    fn new(num_nodes: uint) -> WeightedGraph {
        let mut adjacency_list: ~Vec<~Vec<Edge>> = box Vec::from_fn(num_nodes, |idx| box Vec::new());

        WeightedGraph {
            adjacency_list: adjacency_list,
            size: num_nodes,
            edge_count: 0
        }
    }

    fn add_edge(mut self, source: uint, target: uint, weight: f64) {
        self.adjacency_list.get(source).push(Edge { target: target, weight: weight });
        self.edge_count += 1;
    }
}
因此,有两个主要问题:

1。如何让
add\u edge
方法发挥作用?

我认为WeightedGraph应该拥有它的所有内部数据(如果我错了,请纠正我)。但是为什么
add_edge
不能修改图形自身的数据呢

2。
~Vec
是表示在每个元素中包含动态列表的可变大小数组/列表的正确方法吗?

本教程还提到了
~[int]
作为向量语法,那么它应该是:
~[~[Edge]]]
?或者
Vec
~[Edge]
之间有什么区别?如果我应该使用
~[~[Edge]]
,那么我将如何构造/初始化内部列表?(目前,我尝试使用
Vec::from_fn

  • get
    仅返回不可变引用,如果要修改数据,必须使用
    get_mut
  • 您只需要
    Vec
    ,Vec是正确的使用方式,
    ~[]
    在过去是用于此目的的,但现在意味着其他东西(或将要,不确定是否已经更改)

  • 您还必须更改
    add_edge
    的签名以获取
    &mut self
    ,因为现在您正在将
    self
    的所有权移动到
    add_edge
    ,这不是您想要的权重图确实拥有其所有内部数据,但即使您拥有某些内容,也必须选择对其进行变异
    get
    为您提供了一个
    &
    指针,要进行变异,您需要一个
    &mut
    指针
    Vec::get_mut
    将为您提供:
    self.adjacence_list.get_mut(源代码)。push(…)


    关于
    ~Vec
    ~[Edge]
    :过去(直到最近,
    ~[T]
    表示一个
    T
    的可增长向量,与其他任何类型的
    ~.
    不同,这个特殊情况被删除,
    ~[T]
    现在只是一个指向
    T
    -切片的唯一指针,即,指向内存中一组
    T
    s的指针,没有任何增长能力
    Vec
    现在是可增长的向量类型

    注意,它是
    Vec
    不是
    ~Vec
    ~
    过去是向量语法的一部分,但这里它只是一个普通的唯一指针,表示完全不必要的间接寻址和分配。您需要
    邻接列表:Vec
    Vec
    是一种成熟的具体类型(三重
    数据、长度、容量
    ,如果这对您有任何意义的话),它封装了内存分配和间接寻址,您可以将其用作值。通过
    box
    ing它,您将一无所获,并失去清晰度和性能

    您还有另一个(次要)问题:
    fn add_-edge(mut-self,…)
    ,就像
    fn add_-edge(self,…)
    ,意思是“按值获取
    self
    ”。由于
    邻接列表
    成员是线性类型(它可以是
    drop
    ped,它被移动而不是隐式复制),因此
    WeightedGraph
    也是线性类型。以下代码将失败,因为第一个
    add_edge
    调用消耗了图形

    let g = WeightedGraph::new(2);
    g.add_edge(1, 0, 2); // moving out of g
    g.add_edge(0, 1, 3); // error: use of g after move
    

    您想要
    &mut self
    :允许
    self
    变异,但不要拥有它/不要移动它。

    非常感谢您的详细回答!关于
    ~Vec
    部分:我仍然有点困惑,因为本教程包含使用
    Cons(u32,~list)
    的链表代码(在第9.1节框中)。这让我觉得在另一个结构中引用structs/enum/types需要
    ~
    。那么,链表的
    ~
    仅仅是因为递归方面吗?那么什么是不能直接用作值的“非具体”类型呢?“这个特例被删除了,~[T]现在只是一个指向T片的唯一指针”只是一个迂腐的观点:表示方式的变化还没有发生,所以它仍然表示为一个可增长的向量,但是所有的增长方法(
    .push
    等等)已被删除。希望表示法很快就会改变。@MartinS.,是的,
    ~
    的存在只是为了允许递归。本教程详细解释了指针。目前不能直接用作值的“非具体”类型有
    [T]
    T
    ,其中
    T
    是一个特征。也就是说,您不能使用没有指针的
    [T]
    和trait对象,因为它们的大小未知。教程中也解释了这一点。@dbaupp我知道DST转换尚未完成。但我认为,到目前为止,大家都同意:(1)新的心理模型至少符合API;(2)将DST后的现状描述为现状只是一个暂时的谎言,有助于理解。
    let g = WeightedGraph::new(2);
    g.add_edge(1, 0, 2); // moving out of g
    g.add_edge(0, 1, 3); // error: use of g after move