谢谢楼上大佬回复?
顺便提一下 Rust的官方文档关于可变/不可变引用给了一条限制原则
- 同一个作用域内一个对象的引用只能有两种: 一个可变引用 或者 多个不可变引用.
前者主要解决就是内存别名的问题, 后者主要是解决读写同步的问题.
关于内存别名, 最简单的例子就是交换两块内存里边的内容. 如果有以下的代码:
#include <iostream>
void swap(int* a, int* b)
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
int main(void)
{
int i = 12;
swap(&i, &i);
std::cout << i << std::endl;
return 0;
}
这个时候i
就被set为了0, 原因就是内存别名, 然而, 在Rust中, 不使用raw
指针的情况下, 以下的代码是会编译时出错的.
fn swap(a: &mut i32, b: &mut i32) {
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
fn main() {
let i = 12;
swap(&mut i, &mut i); // 违反了原则: 同一作用域内不能有一个对象的两个可变引用, 报错!
println!("{}", i);
}
另外一个问题就是读写不同步的问题, 以下有这样的一个例子:
#include <iostream>
#include <vector>
int main(void)
{
std::vector<int> v = { 1, 2, 3, 4 };
int j = 0;
for (auto iter = v.begin(); iter != v.end(); ++iter) {
v.push_back(j++); // 每次往vector后边插入一个元素, 尾部发生变化, 这里的iter只读, v可写
}
return 0;
}
这段代码不会报错, 但是死循环.
但是根据Rust的Borrow Rules, 完成同样功能的下边这段代码是不能编译通过的:
fn main() {
let mut v = vec![1, 2, 3];
for i in &v { // v被一个只读引用引用
v.push(*i); // v被一个可变引用应用
}
}