2014-01-16 98 views
3

我對Rust很新,但我正在嘗試着解決如何修改枚舉實例。由於其他原因,我需要使用託管框,但似乎很難改變枚舉的字段。更改Rust中的枚舉字段

#[feature(managed_boxes)]; 

enum State { A(int), B } 

fn main() { 
    let mut state = @A(123); 

    match *state { 
     A(ref mut i) => { *i = 456 } 
     B => { } 
    } 
    println!("{:?}", state) 
} 

我收到錯誤cannot borrow immutable anonymous field as mutablemut似乎只是說變量state是可變的。我想告訴Rust整個事情是可變的。我發現強迫不變性是Rust最令人討厭的事情之一。

回答

3

前段時間託管盒裝有他們自己的可變性「等級」。下面的代碼用於工作:

#[feature(managed_boxes)]; 

enum State { A(int), B } 

fn main() { 
    let state = @mut A(123); 

    match *state { 
     A(ref mut i) => { *i = 456 } 
     B => { } 
    } 
    println!("{:?}", state) 
} 

但是託管盒計劃從語言中刪除。在當前版本的Rust @mut不是有效的標記。您必須使用RefCell,這是一種在託管指針內部提供可變性的可變單元。目前,它看起來有點像這樣:

#[feature(managed_boxes)]; 
use std::cell::RefCell; 

enum State { A(int), B } 

fn main() { 
    let state = @RefCell::new(A(123)); 

    { 
     let mut r = state.borrow_mut(); 
     match r.get() { 
      &A(ref mut i) => { *i = 456 } 
      &B => { } 
     } 
    } 

    println!("{:?}", state) 
} 

你會得到相當廣泛的輸出端上,但因爲它會打印RefCell結構的內部。有關單元的更多信息以及如何使用它們,請參閱documentation on std::cell模塊。

在未來,Rust根本沒有託管框的特殊語法。垃圾收集將在圖書館中實施。我相信代碼將如下所示(Rust作者,請糾正我,如果我錯了):

use std::cell::RefCell; 

enum State { A(int), B } 

fn main() { 
    // state is of type Gc<RefCell<State>> 
    let state = box(Gc) RefCell::new(A(123)); 

    // Dereference will work for library pointer types, not sure about autodereference 
    let mut r = (*state).borrow_mut(); 
    match r.get() { 
     &A(ref mut i) => { *i = 456 } 
     &B => { } 
    } 

    println!("{:?}", *state) 
}