在Rust中更改枚举类型的字段

4

我对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 是可变的。我想告诉 Rust 整个东西都是可变的。我觉得强制不可变性是 Rust 中最让人烦恼的事情之一。

1个回答

4

以前,受管制的 boxed 类型有自己的可变性 "层次结构"。以下代码曾经可以工作:

#[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 结构的内部。有关单元格及其使用方法的更多信息,请参见 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)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接