首先,我知道有很多类似的问题,我也读了很多讨论,但我仍然不明白我的情况是怎么回事.

struct Test {
    x: u32,
}

fn main() {
    let mut t = & mut Test { x: 0 };
    println!("{}", t.x);
    t = & mut Test { x: 1 };
    println!("{}", t.x);
}

好的,这会如预期的那样给出一个错误:

error[E0716]: temporary value dropped while borrowed
 --> src/main.rs:8:15
  |
8 |     t = & mut Test { x: 1 };
  |               ^^^^^^^^^^^^^- temporary value is freed at the end of this statement
  |               |
  |               creates a temporary value which is freed while still in use

"creates a temporary value which is freed while still in use"--没错,但是why doesn't this error happen before呢?只有在第二次赋值&mut时才会发生这种情况,而第一次就可以了.难道它不应该也创造一个被丢弃的临时价值吗?这就是我不能理解的.

此外,如果我删除mut,那么一切都会正常运行:

fn main() {
    let mut t = & Test { x: 0 };
    println!("{}", t.x);
    t = & Test { x: 1 };
    println!("{}", t.x);
}

但是为什么呢?不可变引用仍然是引用,它仍然指向一些数据,并且临时值仍然被删除.因此,引用应该是无效的.也应该给出错误,但不,它没有.为什么?

但等等,还有更多!如果我对Test实现Drop个特征:

impl Drop for Test {
    fn drop(& mut self) {
        
    }
}

现在我又得到了同样的错误,没有更改main()的代码.这有什么关系呢?

推荐答案

为什么

let mut t = &mut Test { x: 0 };

works is described in 为什么 is it legal to borrow a temporary? and the reference:

let语句中的表达式的临时作用域有时会扩展到包含let语句的块的作用域.根据某些语法规则,当通常的临时作用域太小时,就会这样做.

t = &mut Test { x: 1 };

不起作用,因为它不是let的声明,因此没有资格获得相同的终身晋升.

let mut t = &Test { x: 0 };

允许将临时提升为静态(因为它是不可变的) 以下项目也有资格获得constant promotion分:

t = &Test { x: 1 };

所以它起作用了.

因为Drop实现改变了静态变量与局部变量的语义,所以实现它的任何东西都不符合constant promotion的条件,因此问题再次出现(对实现Drop的事物的引用只符合与可变引用相同的作用域扩展的条件).链接的参考文章包含对所有这一切的更全面的解释.

Rust相关问答推荐

为什么拥有的trait对象的相等运算符移动了正确的操作数?

限制未使用的泛型导致编译错误

获取字符串切片(&;str)上的切片([ia..ib])返回字符串

如何编写一个以一个闭包为参数的函数,该函数以另一个闭包为参数?

为什么这是&q;,而让&q;循环是无限循环?

在Rust中是否可以使用Rc自动化约束传播

有没有一种惯用的方法来判断VEC中是否存在变体?

铁 rust 中双倍或更多换行符的更好练习?

为什么AsyncRead在Box上的实现有一个Unpin特征绑定?

通过mem::transmute将数组展平安全吗?

Rust 异步循环函数阻塞了其他future 任务的执行

在1.5n次比较中找到整数向量中的最大和次大整数

从 Axum IntoResponse 获取请求标头

当你删除一个存在于堆栈中的值时,为什么 rust 不会抱怨

n 个范围的笛卡尔积

Rust 异步和 AsRef 未被发送

通用函数中的生命周期扣除和borrow (通用测试需要)

Abortable:悬而未决的期货?

如何制作具有关联类型的特征的类型擦除版本?

为什么在使用 self 时会消耗 struct 而在解构时不会?