我怎样才能使某些结构域可变?

6 struct mutability rust

我有一个结构:

pub struct Test {
    pub x: i32,
    pub y: i32,
}
Run Code Online (Sandbox Code Playgroud)

我想要一个改变这个的功能 - 简单:

pub fn mutateit(&mut self) {
    self.x += 1;
}
Run Code Online (Sandbox Code Playgroud)

这使得整个结构在函数调用的持续时间内是可变的,对mutateit吗?我只是想发生变异x,而我不希望发生变异y.有没有办法可以随意借用x

lje*_*drz 7

引用本书:

Rust不支持语言级别的字段可变性,因此您不能编写如下内容:

struct Point {
    mut x: i32, // This causes an error.
    y: i32,
}
Run Code Online (Sandbox Code Playgroud)

您需要内部可变性,这在标准文档中有很好的描述:

use std::cell::Cell; 

pub struct Test {
    pub x: Cell<i32>,
    pub y: i32
}

fn main() {
    // note lack of mut:
    let test = Test {
        x: Cell::new(1), // interior mutability using Cell
        y: 0
    };

    test.x.set(2);
    assert_eq!(test.x.get(), 2);
}
Run Code Online (Sandbox Code Playgroud)

并且,如果您想将其合并到一个函数中:

impl Test {
    pub fn mutateit(&self) { // note: no mut again
        self.x.set(self.x.get() + 1);
    }
}

fn main() {
    let test = Test {
        x: Cell::new(1),
        y: 0
    };

    test.mutateit();
    assert_eq!(test.x.get(), 2);
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然这有效,但应该注意的是 `std::cell::Cell` 实现了 [!Sync](https://doc.rust-lang.org/std/cell/struct.Cell.html#impl-Sync) ,这意味着该结构不能再在线程之间传递。因此,虽然内部可变性允许某些字段通过不可变引用可变,但它也改变了语义并将“Test”限制为严格的单线程。 (4认同)