rust - 未命名值的范围是什么?

标签 rust

未命名的值何时超出范围,何时删除该值?

我正在寻找基于 official docs 的答案,并非基于实验。

示例 1:

f(foo().bar());

示例 2:

match foo().bar() {
    // ...
}

如果 barfn bar(self) -> ... 它获得传递值的所有权,并且它像往常一样被删除,但是如果 bar 借用,即 fn bar(&self) -> ...? bar 的结果是否取决于 &self 的生命周期是否重要?

也就是说,foo 可能会返回一个 MutexGuard;重要的是要知道守卫何时被丢弃(并且互斥体被解锁)。

实验方法表明,未命名值在创建它的语句“完成”后被删除;强制“提前”删除 let 语句是必需的。

Playground

#[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 a while 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 (the let 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/

相关文章:

async-await - 为什么 `Box<dyn Sink>` 在使用 Tokio 和实验性异步/等待支持时不实现 `Sink` 特征?

rust - 不能借用 `*self` 作为可变的,因为 `self.history[..]` 也被借用为不可变的

generics - 如何在结构/特征、常规变量声明和函数中最好地实现泛型?

arrays - 将一个源数组拆分为多个副本的正确方法是什么?

rust - 无法推断返回包含引用的盒装特征的闭包的生命周期

rust - 将字符串转换为整数?

sockets - 使用 Tokio futures 的多播 UDP 数据包

opengl - 如何在OpenGL中更改纹理的位置?

rust - 我可以在静态向量中包含非静态结构吗

rust - Near-bindgen宏: unsupported argument type