2013-06-02 3 views
4

Я знаю, что изменчивые поля были удалены в 0.6. Я получаю следующую ошибку с этим кодом:Mutable Struct Fields

C:\Users\mflamer\Dropbox\Rust\Tests\gmap.rs:23:8: 23:18 error: assigning to immutable field 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);  
} 

ответ

5

Проблема в том, как изменчивость наследуется посредством собственности. Чтобы что-то изменилось, его владелец должен быть изменчивым. Собственность наследуется, за исключением нового владельца, а @ и & классифицируются как владелец. Таким образом, в этом случае у вас есть dart, владеющий полем @Dart, но не Содержимое коробки, поэтому mut на x не означает, что содержимое коробки изменено (действительно, оно не может быть изменчивым, поскольку в противном случае он может меняться под ногами чего-то другого, что относится к нему).

Способ обойти это либо сделать поле изменчивым полем, так что владелец структуры дротика изменен, т. Е. @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", но это мне не ясно, как заставить его работать в Русте.)

+1

Таковы причины Сейчас я изучаю ржавчину вместо использования Haskell. Я обнаружил, что структуры графов никогда не чувствовали себя совершенно правильно и всегда требовали этих трюков. В очередной раз благодарим за помощь. – MFlamer

+0

Я думаю, нам нужно letrec или ленивый eval, чтобы связать узел. – MFlamer

+0

@MFlamer, существует ленивый eval через [futures] (http://static.rust-lang.org/doc/0.6/std/future.html), но это далеко-весомое решение. – huon

Смежные вопросы