rust 的可变容器不变的元素?

cvxl0en2  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(109)

在Rust中,通常是否可以有一个可变的容器来容纳不可变的值?
示例:

struct TestStruct { value: i32 }

fn test_fn()
{
    let immutable_instance = TestStruct{value: 123};
    let immutable_box = Box::new(immutable_instance);
    let mut mutable_vector = vec!(immutable_box);

    mutable_vector[0].value = 456;
}

在这里,我的TestStruct示例被 Package 在两个容器中:一个Box,然后是一个Vec。从Rust新用户的Angular 来看,令人惊讶的是,将Box移到Vec中会使BoxTestStruct示例都是可变的。
是否有一个类似的结构,其中boxed值是不可变的,但boxes的容器是可变的?更一般地说,是否有可能有多个“层”的容器,而整个树既不是可变的,也不是不可变的?

dzhpxtsq

dzhpxtsq1#

是否有一个类似的结构,其中boxed值是不可变的,但boxes的容器是可变的?更一般地说,是否有可能有多个“层”的容器,而整个树既不是可变的,也不是不可变的?
实际上并不是这样。您可以很容易地创建一个(只需创建一个实现Deref而不是DerefMut的 Package 器对象),但现实是Rust并不真正以这种方式看待(im)可变性,因为它主要关心的是控制共享/可见性。
毕竟,对于一个外部观察者来说,两者之间有什么区别呢

mutable_vector[0].value = 456;

mutable_vector[0] = Box::new(TestStruct{value: 456});


答案是“无”,因为Rust的所有权系统意味着观察者不可能保留原始TestStruct的句柄,因此他们无法知道该结构是否被替换或修改过[1][2]。
如果要保护内部状态,请改用可见性:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8a9346072b32cedcf2fccc0eeb9f55c5

mod foo {
    pub struct TestStruct { value: i32 }
    impl TestStruct {
        pub fn new(value: i32) -> Self { Self { value } }
    }
}

fn test_fn() {
    let immutable_instance = foo::TestStruct{value: 123};
    let immutable_box = Box::new(immutable_instance);
    let mut mutable_vector = vec!(immutable_box);

    mutable_vector[0].value = 456;
}

不会编译,因为从test_fn的观点来看,TestStruct::value是无法存取的。因此,test_fn没有办法变更TestStruct,除非您在它上面加入&mut方法。
[1]:从技术上讲,他们可以检查内存中的地址,这 * 可能 * 会告诉他们,但即使这样,它也不是一个确定的事情(在两个方向上),因此pinning是一个东西。
[2]:这种可观察性的区别也被其他语言所接受,例如Clojure很大程度上福尔斯“所有事物都不可变”的一方,然而它有一个 transients 的概念,允许locally mutable objects

相关问题