未命名值的范围是什么?

时间:2017-10-31 20:58:44

标签: 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

1 个答案:

答案 0 :(得分:2)

来自the reference

  

在大多数左值上下文中使用rvalue时,临时未命名   如果未升级为'static,则会创建并使用左值。   将{rvalue表达式提升到'static插槽时会发生   表达式可以用常量,借用和解除引用来编写   借用表达式是最初写的,没有   改变运行时行为。也就是说,推广的表达可以是   在编译时进行评估,结果值不包含   内部可变性或破坏者(这些属性是确定的   基于可能的值,例如&None总是有类型   &'static Option<_>,因为它不包含任何内容。否则,   临时值的生命周期通常是

     
      
  • 最里面的封闭声明;块的尾部表达式是   被认为是封闭该区块的陈述的一部分,或

  •   
  • 的   条件表达式或循环条件表达式,如果   临时是在if或an的条件表达式中创建的   if / elsewhile表达式的循环条件表达式。

  •   
     

当创建分配到let的临时右值时   但是,声明是在生命周期中创建的   相反,使用封闭语句(let   声明)将是一个保证错误(因为指向   临时存储到变量中,但临时存储   在可以使用变量之前释放)。编译器使用简单   语法规则决定将哪些值分配给let   绑定,因此应该有更长的临时生命。

参考文献中有这些规则的例子。

相关问题