未命名的值何时超出范围,何时删除该值?
我正在寻找基于 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
最佳答案
来自 the reference :
When using an rvalue in most lvalue contexts, a temporary unnamed lvalue is created and used instead, if not promoted to
'static
. Promotion of an rvalue expression to a'static
slot occurs when the expression could be written in a constant, borrowed, and dereferencing that borrow where the expression was the originally written, without changing the runtime behavior. That is, the promoted expression can be evaluated at compile-time and the resulting value does not contain interior mutability or destructors (these properties are determined based on the value where possible, e.g.&None
always has the type&'static Option<_>
, as it contains nothing disallowed). Otherwise, the lifetime of temporary values is typically
the innermost enclosing statement; the tail expression of a block is considered part of the statement that encloses the block, or
the condition expression or the loop conditional expression if the temporary is created in the condition expression of an if or an
if
/else
or in the loop conditional expression of awhile
expression.When a temporary rvalue is being created that is assigned into a
let
declaration, however, the temporary is created with the lifetime of the enclosing block instead, as using the enclosing statement (thelet
declaration) would be a guaranteed error (since a pointer to the temporary would be stored into a variable, but the temporary would be freed before the variable could be used). The compiler uses simple syntactic rules to decide which values are being assigned into a let binding, and therefore deserve a longer temporary lifetime.
引用文献中有这些规则的示例。
关于rust - 未命名值的范围是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53439534/