Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 关于引用的易变性和引用的值的易变性的一些混淆_Rust_Reference_Mutability - Fatal编程技术网

Rust 关于引用的易变性和引用的值的易变性的一些混淆

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指针。经过一些实验和探索,我感到困惑

我熟悉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=&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之间有一些区别,这些区别没有显示在您在问题中引用的表格中

  • 锈迹斑斑

  • Rust具有严格的别名规则,因此一次不能对任何变量有多个可变引用

  • 你的问题(简化)是:为什么我不能对一个可变变量有一个不可变的引用,并通过它对该变量进行变异。但是,如果可以这样做,还可以使用两个引用来修改变量,如下所示:

    设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
    在更多情况下做正确的事情。