提问人:Andrei Nikolaenko 提问时间:4/15/2023 最后编辑:kmdrekoAndrei Nikolaenko 更新时间:9/16/2023 访问量:80
Rust 对温度值的不可变和可变引用是如何删除的?
How are Rust immutable and mutable references to temp values dropped?
问:
首先,我知道有很多类似的问题,我读过很多讨论,但我仍然无法理解我的情况。
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
– 没错,但为什么以前没有发生过这个错误?它只发生在 的第二次赋值上,而第一次赋值就没问题了。难道它不应该也创建一个被丢弃的临时值吗?这是我无法理解的。&mut
此外,如果我删除,那么一切正常:mut
fn main() {
let mut t = & Test { x: 0 };
println!("{}", t.x);
t = & Test { x: 1 };
println!("{}", t.x);
}
但是为什么?不可变的引用仍然是引用,它仍然指向某些数据,并且临时值仍会被删除。所以引用应该是无效的。也应该给出错误,但不,它没有。为什么?
但是等等,还有更多!如果我为以下对象实现特征:Drop
Test
impl Drop for Test {
fn drop(& mut self) { }
}
现在我再次收到相同的错误,而无需更改 中的代码。它有什么关系?main()
答:
3赞
cafce25
4/15/2023
#1
为什么
let mut t = &mut Test { x: 0 };
作品在为什么借用临时的合法? 和参考文献中进行了描述:
语句中表达式的临时作用域有时会扩展到包含该语句的块的作用域。根据某些语法规则,当通常的临时范围太小时,就会这样做。
let
let
t = &mut Test { x: 1 };
不起作用,因为它不是声明,因此没有资格获得相同的终身促销活动。let
let mut t = &Test { x: 0 };
允许将临时提升为静态(因为它是不可变的) 以下人员也有资格持续晋升:
t = &Test { x: 1 };
所以它起作用了。
由于实现更改了静态变量与局部变量的语义,因此实现它的任何内容都不符合持续提升的条件,因此问题再次出现(对实现的事物的引用仅适用于与可变引用相同的范围扩展)。链接的参考文章包含对所有这些的更全面的解释。Drop
Drop
评论
0赞
Andrei Nikolaenko
4/15/2023
虽然我还没有完全理解,但我看到你的答案给出了正确的信息,我只是需要时间来掌握它。因此,我会将您的答案标记为答案,我可能会回来进一步澄清,以使我的问题和您的答案更有用。
评论
let tmp = ...
let tmp = ...