Graph 图结构中的自有指针

Graph 图结构中的自有指针,graph,rust,Graph,Rust,在rust社区的慷慨帮助下,我成功地获得了使用托管指针组装的拓扑数据结构的基础。这一点很好地结合在一起,我对铁锈总的来说很兴奋。然后我读了这篇文章(这似乎是一个合理的计划),它激励我回过头来,如果可能的话,试着只使用自己的指针来重新组装它 这是使用托管指针的工作版本: struct Dart<T> { alpha: ~[@mut Dart<T>], embed: ~[@mut T], tagged: bool } impl<T> Dar

在rust社区的慷慨帮助下,我成功地获得了使用托管指针组装的拓扑数据结构的基础。这一点很好地结合在一起,我对铁锈总的来说很兴奋。然后我读了这篇文章(这似乎是一个合理的计划),它激励我回过头来,如果可能的话,试着只使用自己的指针来重新组装它

这是使用托管指针的工作版本:

struct Dart<T> {
    alpha: ~[@mut Dart<T>],
    embed: ~[@mut T],
   tagged: bool
}

impl<T> Dart<T> {
    pub fn new(dim: uint) -> @mut Dart<T> {
        let mut dart = @mut Dart{alpha: ~[], embed: ~[], tagged: false};        
        dart.alpha = vec::from_elem(dim, dart);              
        return dart;
    }
    pub fn get_dim(&self) -> uint {
        return self.alpha.len();
    }   
    pub fn traverse(@mut self, invs: &[uint], f: &fn(&Dart<T>)) {
        let dim = self.get_dim();
        for invs.each |i| {if *i >= dim {return}}; //test bounds on invs vec
        if invs.len() == 2 {
            let spread:int = int::abs(invs[1] as int - invs[0] as int);
            if spread == 1 { //simple loop
                let mut dart = self;
                let mut i = invs[0];
                while !dart.tagged {
                    dart.tagged = true; 
                    f(dart);
                    dart = dart.alpha[i];
                    if i == invs[0] {i = invs[1];}
                    else {i == invs[0];}
            }   }           
            // else if spread == 2 { // max 4 cells traversed

            // }
        }
        else {
            let mut stack = ~[self];
            self.tagged = true;     
            while !stack.is_empty() {
                let mut dart = stack.pop();
                f(dart);  
                for invs.each |i| {
                    if !dart.alpha[*i].tagged {
                        dart.alpha[*i].tagged = true;
                        stack.push(dart);
}   }   }   }   }   }    
struct-Dart{
阿尔法:~[@mut-Dart],
嵌入:~[@mut T],
标签:布尔
}
插入镖{
新酒吧(尺寸:uint)->@mut Dart{
让mut-dart=@mut-dart{alpha:~[],embed:~[],taged:false};
dart.alpha=vec::from_elem(dim,dart);
回程镖;
}
发布fn获取尺寸(&self)->uint{
返回self.alpha.len();
}   
发布fn遍历(@mut self,invs:&uint,f:&fn(&Dart)){
让dim=self.get_dim();
对于invs.each | i |{if*i>=dim{return};//invs-vec上的测试边界
如果存货长度()==2{
让价差:int=int::abs(invs[1]为int-invs[0]为int);
如果排列==1{//简单循环
让mut-dart=self;
设mut i=invs[0];
同时!飞镖{
dart.taged=true;
f(省道);
省道=省道α[i];
如果i==invs[0]{i=invs[1];}
else{i==invs[0];}
}   }           
//否则,如果排列==2{//最多遍历4个单元格
// }
}
否则{
让mut stack=~[self];
self.taged=true;
while!stack.is_为空(){
让mut dart=stack.pop();
f(省道);
对于每个投资项目| i |{
如果!dart.alpha[*i]。已标记{
dart.alpha[*i].taged=true;
推(镖);
}   }   }   }   }   }    
经过几个小时的跟踪生命周期错误,我得出结论,由于循环的性质,这甚至可能不可能与拥有的指针一起实现(如果不像我那样打结的话)。下面是我在这方面的无力尝试。我的问题是,这个结构是否可以在不使用托管指针的情况下实现?如果不是,上述代码是否被合理地视为“生锈”?(惯用的锈菌)。谢谢

struct GMap<'self,T> {
    dim: uint,
    darts: ~[~Dart<'self,T>]
}   

struct Dart<'self,T> { 
    alpha: ~[&'self mut Dart<'self, T>], 
    embed: ~[&'self mut T], 
    tagged: bool 
}

impl<'self, T> GMap<'self, T> {
    pub fn new_dart(&'self mut self) {
        let mut dart = ~Dart{alpha: ~[], embed: ~[], tagged: false};
        let dartRef: &'self mut Dart<'self, T> = dart;  
        dartRef.alpha = vec::from_elem(self.dim, copy dartRef);
        self.darts.push(dart);              
    }
} 
struct GMap]
}   
结构省{
酒吧新标枪(&'self-mut-self){
让mut-dart=~dart{alpha:~[],嵌入:~[],标记:false};

让dartRef:&'self-mut-Dart我确信使用
&mut
指针是不可能的,因为一次只能有一个这样的指针,例如:

fn main() {
    let mut i = 0;
    let a = &mut i;
    let b = &mut i;
}
通过存储指向内存的不安全指针(
ptr::to_mut\u unsafe\u ptr
),或索引到
GMap
darts
成员,可以不安全地绕过借阅检查器。本质上,存储对内存的单个引用(在
self.darts
),所有操作都必须通过它

这可能看起来像:

impl<'self, T> GMap<'self, T> {
    pub fn new_dart(&'self mut self) {
        let ind = self.darts.len();
        self.darts.push(~Dart{alpha: vec::from_elem(self.dim, ind), embed: ~[], tagged: false});
    }
} 
impl{
酒吧新标枪(&'self-mut-self){
设ind=self.darts.len();
self.darts.push(~Dart{alpha:vec::from_elem(self.dim,ind),embed:~[],taged:false});
}
} 
traverse
需要更改为
GMap
上的一种方法(例如
fn(&mut self,node\u ind:uint,invs:&[uint],f:&fn(&Dart))
),或者至少采用
GMap
类型


(另一个完全不同的方面是,有对的库支持,它比内部迭代器(采用闭包的迭代器)更具可组合性。因此为
遍历定义其中一个可能(也可能不)使使用它更方便。)

看起来像是托管指针版本(GC或RC)的开销在这种情况下可能是值得的。如果我使用地图或哈希表来保持省道笔直,无论如何都会有一些开销。谢谢。除非使用地图和拥有的指针使我能够并行遍历…还不确定。
impl<'self, T> GMap<'self, T> {
    pub fn new_dart(&'self mut self) {
        let ind = self.darts.len();
        self.darts.push(~Dart{alpha: vec::from_elem(self.dim, ind), embed: ~[], tagged: false});
    }
}