为什么Rust允许升级/降级可变性?
在 Rust 中,你可以升级一个不可变的变量:
let v = Vec::new(); // Immutable
let mut v = v; // Mutable
v.push("hi"); // Succeeds
或者降级一个可变变量:
let mut v = Vec::new(); // Mutable
let v = v; // Immutable
v.push("hi"); // Won't compile
我的问题是——为什么?
据我了解,用于存储变量值的底层内存永远不会是一成不变的。从技术上讲,每个内存地址都可以写入。不变性是一种人为的约束,有人为我们设置的(如内核),或者我们为自己设置的。
当我说:
let v = vec!["a", "b", "c"];
我是说我想要一个具有这些值的内存变量,并且我不希望以后任何代码更改它。如果我试图在某个时候改变这个变量,给我一个错误。这是我定义的约束。
如果以后可以,请执行以下操作:
let mut v = v;
使它可变,并改变它,这似乎违背了不可变变量的全部目的。在这一点上,您不妨让所有变量都可变(就像在 Python 中一样),因为不保证不变性。不仅不能保证,而且程序员可能会对不变性的保证产生错误的认识,并基于这种假设犯错误。
至少对于常量,有不变性的保证。如果您可以在任何时候使其可变,则常规不可变变量的目的尚不清楚。
回答
在 Rust 中,你可以升级一个不可变的变量:
let v = Vec::new(); // Immutable let mut v = v; // Mutable v.push("hi"); // Succeeds
这不是升级变量。您正在创建一个变量v并将其移动到另一个也称为v. 原版v已无法访问。在调试模式下,生成的代码可能有两个完全不同的(堆栈)内存地址用于第一个和第二个v。
至于降级,同样适用。
这似乎违背了不可变变量的全部目的。
一旦您移动了一个值,您就不能再使用它,并且如果存在对该值的引用,您将无法移动该值。因此,您永远不会遇到对现在不可变的事物有可变引用的情况。