【问题标题】:How does borrowing Box<Trait> contents work?借用 Box<Trait> 内容如何工作?
【发布时间】:2017-05-31 16:06:30
【问题描述】:

我有this minimal example code:

use std::borrow::BorrowMut;

trait Foo {}
struct Bar;
impl Foo for Bar {}

fn main() {
    let mut encryptor: Box<Foo> = Box::new(Bar);

    encrypt(encryptor.borrow_mut());
}

fn encrypt(encryptor: &mut Foo) { }

但它失败并出现此错误:

error: `encryptor` does not live long enough
  --> src/main.rs:11:1
   |
10 |     encrypt(encryptor.borrow_mut());
   |             --------- borrow occurs here
11 | }
   | ^ `encryptor` dropped here while still borrowed
   |
   = note: values in a scope are dropped in the opposite order they are created

#rustbeginners 的好心人发现我必须取消引用框才能获取内容,然后借用内容。 Like this:

trait Foo {}
struct Bar;
impl Foo for Bar {}

fn main() {
    let mut encryptor: Box<Foo> = Box::new(Bar);

    encrypt(&mut *encryptor);
}

fn encrypt(encryptor: &mut Foo) { }

有效,但我不明白。

为什么我需要先取消引用?试图说的错误是什么?通常,在函数末尾删除值不是错误。


显然,不只是我不明白这是如何工作的;一个issue has been filed

【问题讨论】:

标签: rust traits borrow-checker


【解决方案1】:

让我们从允许代码工作的更改开始:

fn encrypt(encryptor: &mut (Foo + 'static)) { }

重要的区别是将 + 'static 添加到 trait 对象 - 括号只是优先级所必需的。

重要的是要认识到are two lifetimes present in &amp;Foo:

  • 引用本身的生命周期:&amp;'a Foo
  • 代表特征抽象的具体值内的所有引用的生命周期:&amp;(Foo + 'b)

如果我正确阅读了 RFC,这是由 RFC 192 引入的,RFC 599 为生命周期指定了合理的默认值。在这种情况下,生命周期应该扩展为:

fn encrypt(encryptor: &mut Foo) { }
fn encrypt<'a>(encryptor: &'a mut (Foo + 'a)) { }

在管道的另一端,我们有一个Box&lt;Foo&gt;。通过 RFC 的规则扩展,它变成了Box&lt;Foo + 'static&gt;。当我们借用它并尝试将其传递给函数时,我们有一个方程要求解:

  • 特征对象内的生命周期是'static
  • 该函数采用对特征对象的引用。
  • 引用的生命周期等于特征对象内引用的生命周期。
  • 因此,对特征对象的引用必须是'static。哦哦!

Box 将被丢弃在块的末尾,所以它肯定不是静态的。

具有显式生命周期的修复允许 trait 对象的引用的生命周期与 inside trait 对象的引用的生命周期不同。

如果您需要支持带有内部引用的 trait 对象,另一种方法是执行以下操作:

fn encrypt<'a>(encryptor: &mut (Foo + 'a)) { }

这个解释的真正功劳goes to nikomatsakis and his comment on GitHub,我只是扩展了一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-04
    • 1970-01-01
    • 2021-05-01
    相关资源
    最近更新 更多