【发布时间】:2020-10-03 15:14:31
【问题描述】:
我有以下程序:
fn main() {
let x = 0;
println!("Example 1: {:p}", &x);
println!("Example 1: {:p}", &x);
println!("Example 2: {:p}", &&x);
println!("Example 2: {:p}", &&x);
}
这是一个示例输出:
Example 1: 0x7ffcb4e72144
Example 1: 0x7ffcb4e72144
Example 2: 0x7ffcb4e72238
Example 2: 0x7ffcb4e72290
"Example 1" 的输出始终相同,而 "Example 2" 的输出始终不同。
我读过Does println! borrow or own the variable?,我从给定的答案中了解到println! 默默地引用了一个引用。换句话说,这听起来像println! 增加了额外的间接级别。
我曾预计"Example 1" 的输出也会有所不同。看到println! 默默地采取了另一个级别的间接,"Example 1" 实际上正在与&&x 合作,而"Example 2" 正在与&&&x 合作。这似乎与我链接的答案一致,特别是:"If you write println!("{}", &x), you are then dealing with two levels of references"。
我认为值&&xholds 将为"Example 1" 打印,而值&&&xholds 将为"Example 2" 打印。 &&x 和 &&&x 都持有一个临时的 &x,所以我认为 "Example 1" 也会打印不同的地址。
我哪里错了?为什么"Example 1" 没有打印不同的地址?
【问题讨论】:
-
为什么x的地址要改变?
&&x是x的地址,当你临时创建这个变量时,两个文字&&x值相等是未指定的。 println 只为非复制类型借用,所有引用都可以复制,所以它们不会被 println 借用。 -
@SCappella 我不这么认为,因为该问题的答案涉及
Display的行为,它适用于{}而不是{:p}。 -
@Stargateur 我的理解是
println!不管是不是非拷贝类型都会借用。例如,我链接的问题的答案在底部:If you write println!("{}", &x), you are then dealing with two levels of references。听起来甚至对x的引用也应用了额外的间接级别。 -
@MarioIshac 好吧,反正你让 println 打印 &x 的值,所以即使宏带一个 &&x,它也会显示你问的所以 &x,如果有两个也没关系间接级别(我很确定最终 asm 会摆脱它)。您需要了解的是
&x与&&x非常不同。