【问题标题】:Reference to temporary returned from a function对从函数返回的临时对象的引用
【发布时间】:2021-03-13 02:59:53
【问题描述】:

我在尝试回答 this question 时遇到了这个谜题。

如何/为什么编译:


#[derive(Debug,Default)]
struct Foo {
    i: i32
}

#[derive(Debug)]
struct Bar<'a> {
    foo: &'a Foo
}

impl<'a> Default for Bar<'a> {
    fn default() -> Self {
        Bar {
            foo: &Foo{ i: 25 }
        }
    }
}

fn main() {
    let bar : Bar = Default::default();
    println!("{:?}", bar);
}

Playground

我们创建一个Bar 的实例,其中包含对Foo 的引用,但谁拥有Foo?它是在 default() 函数中匿名创建的,所以我期待一个错误,指出对它的引用超过了它的范围。

如果我更改 default() 实现,则会收到预期的错误:

    fn default() -> Self {
        let foo = Foo{ i: 25 };
        Bar {
            foo: &foo
        }
    }
error[E0515]: cannot return value referencing local variable `foo`
  --> src/main.rs:15:9
   |
15 | /         Bar {
16 | |             foo: &foo
   | |                  ---- `foo` is borrowed here
17 | |         }
   | |_________^ returns a value referencing data owned by the current function

我阅读了参考文献中与 temporary scopes 相关的部分 - 我没有发现临时范围可能超出函数范围的任何情况。

【问题讨论】:

    标签: rust borrow-checker


    【解决方案1】:

    这是由于Constant Promotion:

    将值表达式提升到'static 槽时,当表达式可以写入常量、借用并取消引用最初写入表达式的借用位置时,就会发生这种情况,而不会更改运行时行为。也就是说,提升的表达式可以在编译时评估,结果值不包含interior mutabilitydestructors(这些属性是根据可能的值确定的,例如&amp;None 始终具有&amp;'static Option&lt;_&gt; 类型,因为它不包含任何不允许的内容)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多