我目前正在进行实验,同时试图学习铁 rust . 我看到有可能引用它自己的地址(下面是y = &y),然而,由于某些原因,程序仍然能够找到引用最初指向的是什么;

let x = 1;
let mut y = &x;
println!("{y:p} -> {y}"); // 0x7fffb13d6f6c -> 1
y = &y;
println!("{y:p} -> {y}"); // 0x7fffb13d6f6c -> 1

我所理解的是,在第二行之后,记忆如下所示;

name address value
x a1 1
y a2 a1

如果指令y = &y正在将存储器变成这样;

name address value
x a1 1
y a2 a2

println!将能够输出它在最后一行上输出的内容,那么第四行到底是做什么的,它之后的内存是什么样子的?

推荐答案

y并不指向它自己.这是不可能的.y点正好是它之前指向的地方,而赋值y = &y什么都不做.

那么它意味着什么,为什么要编译它呢?

要回答这个问题,我们需要看一下类型.这里有一件神秘的事情:如果y的类型是&i32,那么&y的类型是&&i32,那么当它们是完全不同的类型时,如何能够将&y赋给y呢?

答案是背信弃义的胁迫.当您编写y = &y时,编译器会try 匹配类型.它不能将&&i32&i32匹配,但它试图提供帮助,并认为:"可能程序员有一些引用,他想要取消引用,但只是没有显式地写出来.所以我会为他这样做!"例如,这对于将&String传递给采用&str的函数是有用的.&String&str的类型不同,但Stringstr的类型不同,所以我们可以将它转换为&**s,首先从&String创建String,然后从&String创建str,最后引用它来创建&str.

所以,y = &y相当于y = &*y.它只接受一个引用,然后立即取消对它的引用,也就是说,只是将y中的值再次复制到y中,有效地保留了它.

Rust相关问答推荐

为什么我的梅森素数代码的指数越大,速度就越快?

在函数内定义impl和在函数外定义impl的区别

修改切片/引用数组

通过不同的字段进行散列和排序的 struct (需要不同的EQ实现)

铁 rust 中的共享对象实现特征

try 创建随机数以常量

我们能确定Rust会优化掉Clone()吗?如果它会立即掉落?

类型生命周期绑定的目的是什么?

std mpsc 发送者通道在闭包中使用时关闭

Rust 如何返回大类型(优化前)?

当没有实际结果时,如何在 Rust 中强制执行错误处理?

如何使用 Bincode 在 Rust 中序列化 Enum,同时保留 Enum 判别式而不是索引?

有没有办法隐式绑定 let/match 操作的成员?

在 Rust 中实现资源消耗的安全包装器

如何判断服务器是否正确接收数据

在 Rust 中,我如何处理请求 javascript 的页面?

返回迭代器的特征

在构建器模式中捕获 &str 时如何使用生命周期?

无法理解 Rust 对临时值的不可变和可变引用是如何被删除的

在 macro_rules 中转义 $ 美元符号