下面,我的TestStruct
示例被 Package 在两个容器中:一个Box
,然后一个Vec
。从一个新的Rust用户的Angular 来看,将Box
移动到Vec
中会使Box
和TestStruct
示例都是可变的,这是令人惊讶的。
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;
}
有没有类似的构造,使装箱的值是不可变的,但箱的容器是可变的?更一般地说,有没有可能有多个“层”的容器,而整个树既不是可变的,也不是不可变的?
1条答案
按热度按时间whhtz7ly1#
有没有类似的构造,使装箱的值是不可变的,但箱的容器是可变的?更一般地说,有没有可能有多个“层”的容器,而整个树既不是可变的,也不是不可变的?
你可以很容易地创建一个(只需创建一个实现
Deref
而不是DerefMut
的 Package 器对象),但现实是Rust并不真正以这种方式看到(im)可变性,因为它主要关注的是控制共享/可见性。毕竟,对于外部观察者来说,
和
?
答案是没有,因为Rust的所有权系统意味着观察者不可能保持对原始
TestStruct
的处理,因此他们无法知道该结构是否被替换或修改。如果你想保护你的内部状态,请使用可见性:https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8a9346072b32cedcf2fccc0eeb9f55c5
无法编译,因为从
test_fn
的Angular 来看,TestStruct::value
是不可访问的。因此,test_fn
无法改变TestStruct
,除非您在其上添加&mut
方法。[1]:从技术上讲,他们可以检查内存中的地址,这 * 可能 * 会告诉他们,但即使这样,它也不是一个确定的事情(在任何一个方向上),因此pinning是一个东西。
[2]:这种可观察性的区别也被其他语言所接受,例如Clojure在很大程度上福尔斯属于“所有事物都是不变的”,但是它有一个 * transient * 的概念,允许locally mutable objects