当未命名的值超出范围时,值何时被删除?
我正在寻找基于official docs的答案,而不是基于实验。
示例1:
f(foo().bar());
示例2:
match foo().bar() {
// ...
}
如果bar
为fn bar(self) -> ...
,它将获取所传递值的所有权,并且会像往常一样被删除,但如果bar
借用,即fn bar(&self) -> ...
会怎样? bar
的结果是否取决于&self
的生命周期是否重要?
也就是说,foo
可能会返回MutexGuard
;必须知道防护装置何时掉落(并且互斥锁已解锁)。
实验方法显示,在创建语句后,未命名的值将被“删除”;要强制“早期”删除,需要let
语句。
#[derive(Debug)]
pub struct Foo;
pub fn foo() -> Foo {
println!("foo()");
Foo
}
impl Foo {
pub fn bar(&self) {
}
}
impl Drop for Foo {
fn drop(&mut self) {
println!("Foo::drop()");
}
}
fn main() {
println!("--- scope test start");
println!("value: {:?}", foo().bar());
println!("--- end");
println!("--- scope test start");
match foo().bar() {
v => println!("value: {:?}", v),
}
println!("--- end");
println!("--- scope test start");
let v = foo().bar();
println!("value: {:?}", v);
println!("--- end");
}
打印:
--- scope test start
foo()
value: ()
Foo::drop()
--- end
--- scope test start
foo()
value: ()
Foo::drop()
--- end
--- scope test start
foo()
Foo::drop()
value: ()
--- end
答案 0 :(得分:2)
在大多数左值上下文中使用rvalue时,临时未命名 如果未升级为
'static
,则会创建并使用左值。 将{rvalue表达式提升到'static
插槽时会发生 表达式可以用常量,借用和解除引用来编写 借用表达式是最初写的,没有 改变运行时行为。也就是说,推广的表达可以是 在编译时进行评估,结果值不包含 内部可变性或破坏者(这些属性是确定的 基于可能的值,例如&None
总是有类型&'static Option<_>
,因为它不包含任何内容。否则, 临时值的生命周期通常是
最里面的封闭声明;块的尾部表达式是 被认为是封闭该区块的陈述的一部分,或
的 条件表达式或循环条件表达式,如果 临时是在if或an的条件表达式中创建的
if
/else
或while
表达式的循环条件表达式。当创建分配到
let
的临时右值时 但是,声明是在生命周期中创建的 相反,使用封闭语句(let
声明)将是一个保证错误(因为指向 临时存储到变量中,但临时存储 在可以使用变量之前释放)。编译器使用简单 语法规则决定将哪些值分配给let 绑定,因此应该有更长的临时生命。
参考文献中有这些规则的例子。