2013-06-02 53 views
4

我知道可變字段在0.6中被刪除。我收到以下錯誤代碼,可變結構字段

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框,但不是框的內容,所以mutx並不意味着框的內容是可變的(的確是不可變的,因爲否則它可能會在引用它的別的東西的腳下改變)。

解決這個問題的方法是使框變爲可變框,以便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",但它不是我清楚如何得到它的魯斯特工作)。

+1

這些都是原因現在我正在學習生鏽,而不是使用Haskell。我發現圖形結構從來沒有覺得很正確,總是需要這些技巧。再次感謝你的幫助。 – MFlamer

+0

我想我們需要letrec或​​lazy eval來打結。 – MFlamer

+0

@MFlamer,通過[期貨](http://static.rust-lang.org/doc/0.6/std/future.html)有懶惰的評估,但這是一個非常重的解決方案。 – huon

相關問題