2014-01-16 3 views
3

Я очень новичок в Rust, но я пытаюсь решить, как изменить экземпляр enum. Мне нужно использовать управляемые ящики по другим причинам, но, похоже, сложно сменить поле перечисления.Изменение поля enum в 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 mutable. mut, по-видимому, только говорит, что state, переменная, является изменяемой. Я хочу сказать Русту, что все это изменчиво. Я нахожу вынужденную неизменность одной из самых раздражающих вещей ржавчины.

ответ

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) 
} 
Смежные вопросы