Rust 关于引用的易变性和引用的值的易变性的一些混淆
我知道锈引用很像C指针,我一直认为锈引用是C指针。经过一些实验和探索,我感到困惑 我熟悉C语言,我读过,它给出了下表:Rust 关于引用的易变性和引用的值的易变性的一些混淆,rust,reference,mutability,Rust,Reference,Mutability,我知道锈引用很像C指针,我一直认为锈引用是C指针。经过一些实验和探索,我感到困惑 我熟悉C语言,我读过,它给出了下表: //铁锈C/C++ a:&T==常数T*常数a;//也不能变异 mut a:&T==const T*a;//不能改变所指向的内容 a:&mut T==T*常数a;//不能改变指针 mut a:&mut T T==T*a;//两者都可以变异 这篇文章的票数被提高了,所以我认为它是正确的 我写了下面的代码 fn main(){ 设mut x=10; 设x1=&mut x; 设x2
//铁锈C/C++
a:&T==常数T*常数a;//也不能变异
mut a:&T==const T*a;//不能改变所指向的内容
a:&mut T==T*常数a;//不能改变指针
mut a:&mut T T==T*a;//两者都可以变异
这篇文章的票数被提高了,所以我认为它是正确的
我写了下面的代码
fn main(){
设mut x=10;
设x1=&mut x;
设x2=&x1;
设x3=&x2;
***x3=20;
}
希望它相当于下面的C代码
intmain(){
int x=10;
int*常数x1=&x;
int*const*constx2=&x1;
int*const*const*constx3=&x2;
***x3=20;
返回0;
}
Rust代码不编译:
error[E0594]:无法分配到`&`引用后面的`***x3`
-->src/main.rs:6:5
|
6 |***x3=20;
|^^^^^^^^^^^无法分配
这里怎么了
奇怪的是,下面的代码可以编译
fn main(){
设mut x=10;
设mut-x1=&mut-x;
设mut x2=&mut x1;
设mut x3=&mut x2;
***x3=20;
}
为什么要使用
让mut x1/2/3
而不仅仅是让x1/2/3
?我认为x1=&mut x是一个常量指针,指向一个可变变量x
。堆栈溢出帖子是不准确还是我误解了它?Rust和C之间有一些区别,这些区别没有显示在您在问题中引用的表格中
设mut x=10;
设x1=&mut x;
设x2=&x1;//对x1的不可变引用,ok
设x3=&x1;//对x1的另一个不可变引用,好吗
**x2=20;//哦,现在我可以通过两个参考来变异“x”!
**x3=30;
关于你的C相当于给定的锈代码-你没有根据表翻译它。考虑这一点:
设x2=&x1;
从您引用的答案中的表格中:
a:&T==const T*const a;//不能修改任何一个
在这种情况下,T将是const int*
。因此,它将是:
const int* const* const x2 = &x1;
int main() {
// let mut x = 10;
int x = 10;
// let x1 = &mut x;
// a: &mut T == T* const a with T=int
int* const x1 = &x;
// let x2 = &x1;
// a: &T == const T* const a with T = int* const
const int* const* const x2 = (const int* const* const) &x1;
// let x3 = &x2;
// a: &T == const T* const a with T = const int* const* const
const const int* const* const* const x3 = &x2;
***x3 = 20;
return 0;
}
你的整个计划是:
const int* const* const x2 = &x1;
int main() {
// let mut x = 10;
int x = 10;
// let x1 = &mut x;
// a: &mut T == T* const a with T=int
int* const x1 = &x;
// let x2 = &x1;
// a: &T == const T* const a with T = int* const
const int* const* const x2 = (const int* const* const) &x1;
// let x3 = &x2;
// a: &T == const T* const a with T = const int* const* const
const const int* const* const* const x3 = &x2;
***x3 = 20;
return 0;
}
请注意,需要强制转换以避免x2赋值中出现警告。这是一条重要线索:我们正在有效地向指向的对象添加常量
如果您尝试编译,您会得到:
t.c:在函数“main”中:
t、 c:17:11:错误:分配只读位置“***x3”
***x3=20;
^
在Rust中有点不同。&符号表示引用某物,*符号表示取消引用某物。如果我的内存没有问题,C/C++语法会使用'->'符号(这是一种取消引用的方式),它不会出现在Rust中
Rust最难的部分是跟踪谁借了什么。一旦您了解了它是如何工作的,并且了解了哪些数据类型利用了哪些数据类型(例如,Vec!利用了堆):您应该非常精通Rust 从问题中的表格中,
让x1=&mut x2代码>应翻译为int*const x1=&x2代码>(表中的第三行)。然后每个阶段都应该在类型前面添加一个const
,在后面添加一个(第一行)。我不认为您的意思是要添加const
。如果T
为const int*
则const T*const
为const int*const
。在这种情况下使用“east const”会比较容易理解:&T==T const*const
。谢谢@Jmb,已经修复。这就是尝试过快地写太多C jibberish的结果!谢谢@TavianBarnes。我在程序主体中正确,但在顶部部分不正确。我不确定我是否更喜欢east const版本而不是west版本,虽然我也不太喜欢east const,但它确实允许简单的文本替换,如t->t const*const
在更多情况下做正确的事情。