开发知识

Rust: 如何区分可变引用还是可变变量?&mut VS mut

来源: coding到灯火阑珊  日期:2024-04-26 22:36:29  点击:14  属于:开发知识

变量

要在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;

我们创建了两个引用,其中一个是可变引用,另一个是只读引用。

图片图片

在给定的4个变量中,其中2个是引用,这两个引用变量都是不可变的,在let之后没有mut关键字,这意味着我不能更改它们指向的内容。但是,我仍然可以更改它们引用的值。

*x_ref = 777;

如果你这样写,Rust编译器不会报错,x的值(不是ref本身)会变成777。那么,为什么我可以改变它所指向的值呢?

在没有任何隐式类型推导的形式下,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!

图片图片

让我们修改代码:

let mut x: i32 = 1337;
let mut x_ref: &mut i32 = &mut x; // 在x_ref前面加了mut
let mut z = 0;

x_ref = &mut z; // Allowed!

x_ref周围有太多的mut,让我们来描述一下:

1,let mut x_ref:我们正在创建一个名为x_ref的可变变量,这意味着可以稍后更改它的值。

2,&mut i32:声明该变量为i32类型的可变引用

3,&mut x:x变量的可变借用

然后,创建了一个名为z的变量,并将其赋值为0。之后,当写x_ref = &mut z时,x_ref是一个可变变量,保存对i32值的可变引用。

图片图片

让我们看一下语句:

let mut x_ref = &mut x;

以等号分割成两个子语句:左边提供关于变量本身的信息,而右边告诉我们关于变量的值。

当使用“ * ”解引用操作符来改变值时

*x_ref = 100;

没有改变x_ref变量的值。相反,改变了x_ref引用的值。

不可变引用

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; // 这是允许的
*k = 3; // 这是不允许的

图片图片

总结

在本文中,我们剖析了mut关键字和引用之间的细微差别。记住,可变引用和持有引用的可变变量是有区别的。