关于Rust引用与指针的讨论

在Rust/CPP中,我们会学习到一个新概念叫做引用,这是对指针的更高级别抽象,引用可以看作对一个对象的别名,相当于你用一个别名来代替原对象并进行相关操作,而且不会内存占用且在函数传参时不会发生内存拷贝。引用相比于指针,更能实现安全的内存操作。这也是为什么rust会采用引用作为指针的抽象。

引用的最大特点是初始化引用后不能修改引用的指向,这样极大的保证了不会出现指针的访问无效内存。

在b站上有个人针对初始化后不能改变引用的指向这句话发出了反驳,是rust代码,代码如下:

1
2
3
4
5
fn main() {
  let mut r=&0;
  let a=&7;
  r=&a;
}

他指出此代码中r被定义为可变引用,第三行可以改变原引用的指向,因此可以推导出引用初始化后可以改变。

错误在哪呢?

首先我们要了解rust的引用与解引用和CPP的引用和其他语言的取地址符号的关系。rust的&操作其实是与cpp不同,cpp分左值引用与右值引用,在讨论类似的左值引用时,cpp的格式如下

1
2
3
4
int main(){
    int a=1;
    int &b=a;
}

在这个例子中,我们知道rust的可变引用就是实现在借用时改变能借用数据,在此时实例中r 为字面量0的可变引用,可是对字面量的可变引用意义在哪?字面量值是不可更改的!

那么如何去理解这个可变引用?

rust官方给出两个名词叫做引用与解引用,可以将&理解为cpp的取地址符,这里声明了一个变量r用于存储字面量0的地址,a用于存储字面量7的内存地址,然后将a的内存地址赋给r,第三行r的内容变为了a字面量的地址。