可变结构域

时间:2013-06-02 02:47:24

标签: rust

我知道0.6中删除了可变字段。我在这段代码中遇到以下错误,

  

C:\ Users \ mflamer \ Dropbox \ Rust \ Tests \ gmap.rs:23:8:23:18错误:   分配到不可变字段   C:\ Users \ mflamer \ Dropbox \ Rust \ Tests \ gmap.rs:23 dart.alpha =   vec :: from_elem(self.n + 1,dart);

我在这里做错了什么?感谢。

pub struct GMap<T> {
        priv     n: uint,
        priv darts: ~[Dart<T>]
    }

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

impl<T> GMap<T> {
    pub fn new(dim: uint) -> GMap<T> {      
        let mut map: GMap<T> = GMap{n: dim, darts: ~[]};
        return map
    }
    pub fn new_dart(&self, ) -> @Dart<T> {
        let mut dart = @Dart{alpha: ~[], embed: ~[], tagged: false};        
        dart.alpha = vec::from_elem(self.n + 1, dart); 
        //dart.embed = vec::from_elem(self.n + 1, );
        return dart;
    }
    pub fn dim(&self) -> uint {
        self.n 
    }
}


//pub fn traverse(&self,[bool,..])


enum Cell {
    Null,
    Vertex,
    Edge,
    Face,
    Solid
}   

fn main() { 
    let topo: GMap<Cell> = GMap::new(3);    
}

1 个答案:

答案 0 :(得分:6)

问题在于可变性是如何通过所有权继承的。对于可变的东西,它的拥有者必须是可变的。除了通过新所有者之外,所有权继承,@&被归类为所有者。因此,在这种情况下,您dart拥有@Dart框,但框中的内容,因此mut上的x不会这意味着盒子的内容是可变的(实际上,它不可能是可变的,因为否则它可能会在引用它的其他东西的脚下发生变化)。

解决这个问题的方法是让盒子变成一个可变的盒子,这样dart结构的所有者是可变的,即@mut Dart { .. }(这有一个(小的)运行时惩罚,并且可以使程序成为可能失败,如果它被借用作为不可变的变异),或者一次性构建它。前者不是最优的,后者听起来很难实现。但是,前者可能看起来像:

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

// ...

    pub fn new_dart(&self, ) -> @mut Dart<T> {
        let dart = @mut Dart{alpha: ~[], embed: ~[], tagged: false};        
        dart.alpha = vec::from_elem(self.n + 1, dart); 
        //dart.embed = vec::from_elem(self.n + 1, );
        return dart;
    }

(非@mut解决方案需要的是"tying the knot",但我不清楚如何让它在Rust中运行。)