【问题标题】:Changing a enum's field in Rust在 Rust 中更改枚举的字段
【发布时间】:2026-01-25 23:10:01
【问题描述】:

我对 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 最烦人的事情之一。

【问题讨论】:

    标签: oop enums rust


    【解决方案1】:

    前段时间,管理盒装有自己的可变性“层次结构”。下面的代码曾经工作过:

    #[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)
    }
    

    【讨论】: