介绍 尽管 Rust 提供了 Rust 书籍,但我还是很难理解 关键字。我问自己:“我是唯一一个有这个问题的人吗?”谷歌的快速搜索证实我并不孤单。 mut 因此,我决定写这篇文章来详细解释 关键字。本文适用于那些使用过 Python 或 JavaScript 等高级语言的人。 mut 变量 要在 Rust 中创建不可变变量,只需编写 。这很简单。如果你想创建一个可以稍后修改的变量,只需在 后面添加 关键字即可。 Rust 有一个有用的约定,鼓励明确意图。 let x = 1337 let mut 添加 关键字会通知其他人该变量将在代码中的其他位置进行修改。好的。 mut 让我们想象一下。这里有两个变量, 和 。 let mut x = 1337 let y = 42 参考文献 目前,一切都很简单。然而,当使用 引用时,事情开始变得有点复杂。让我们创建一些。 mut let mut x = 1337; let y = 42; let x_ref = &mut x; let y_ref = &y; 我创建了两个引用(或者用 Rust 的术语“借用”)。其中一个是可变引用,另一个是只读引用。让我们再次为此创建一个方案。 在给定的方案中,我有 4 个变量,其中 2 个是引用。两个引用变量都是不可变的,并且在 之后没有 关键字,这意味着我无法更改它们指向的内容。但是,我仍然可以更改它们引用的值。 let mut *x_ref = 777; 如果你这样写,Rust 编译器不会抱怨,并且 的值(不是 ref 本身)将更改为 。然而,该方案上有一个红色方块,表明 缺少可变性选项。那么,为什么我可以改变它所指的值呢? x 777 x_ref 让我们回到 的方案。 let x_ref = &mut x 第一个白色块包含名称: 。第二个告诉我该变量中存储的类型。在其完整形式中,没有任何隐式类型注释,我可以编写如下: x_ref let x_ref: &mut i32 = &mut x; 我可以将其解释为:让我们创建一个名为 的 ,它将保存对 ,并立即使用 变量中对 值的 对其进行初始化。 x_ref 不可变变量 i32 可变引用 x i32 可变引用 这意味着我可以修改它指向的值,但无法更改引用的值(或地址)。换句话说,我不能写这样的东西: let x_ref: &mut i32 = &mut x; let mut z = 0; x_ref = &mut z; // Not allowed! 就方案而言,我想更改上面代码块中箭头指向的方向。但是,即使 变量是可变的,我也无法更改箭头,因为问题在于 本身的不可变性。 z x_ref 要更改箭头方向,我需要修改 变量中存储的地址。但是,我不能这样做,因为变量是不可变的。 x_ref 我们开始做吧! let mut x: i32 = 1337; let mut x_ref: &mut i32 = &mut x; // I've added mut before x_ref let mut z = 0; x_ref = &mut z; // Allowed! 周围有太多 实例,对吗?让我们来描述一下它们。 x_ref mut :我正在创建一个名为 的可变变量,这意味着我可以稍后更改它的值。 let mut x_ref x_ref :我声明该变量将包含对 类型的某些值的可变引用。 &mut i32 i32 :我借用(引用)变量 。 &mut x x 然后,我创建了一个名为 的变量并为其指定了值 。后来,当我写 时,我表示我理解 是一个可变变量,只能保存对 值的引用。 z 0 x_ref = &mut z x_ref i32 由于 的类型是 ,我可以将其地址分配给 变量。为了获取 的地址,我使用了 语法。 z i32 x_ref z &mut z 方案。 心理诡计 看看语句中的 ,可能看起来有点明显,但是…… = let mut x_ref = &mut x; …我将其视为一个分隔符(特别是如果将其旋转 90 度),将语句分为两个子语句:左和右。左侧提供 本身的信息,而右侧则告诉我们 。 有关变量 有关值的信息 当我使用 取消引用运算符来更改值时... * *x_ref = 100; ...我不更改 变量的值。相反,我正在更改 引用的值。 x_ref x_ref 不可变的引用 我以前经常使用 。如果我省略其中一些怎么办? mut let i = 1; let j = 2; let mut k = &i; 我可以改变这里的 值吗?使用分隔符技术,回答起来非常简单。我可以更改 的值(我在左侧看到 ),但值(右侧)是对 不可变引用(这里没有 )。 i k mut i mut 所以… let i = 1; let j = 2; let mut k = &i; k = &j; // This is legal. *k = 3; // This is not. 方案。 结论 在本文中,我们剖析了 关键字和引用的细微差别。请记住, 和 之间是有区别的。我们的伎俩? mut 可变引用 持有引用的可变变量 使用 符号作为心理分隔符可以更好地理解 Rust 中的赋值。这个简单的可视化可以消除许多困惑。 = 快乐编码!