繁体   English   中英

如何借用Box <Trait> 内容有效吗?

[英]How does borrowing Box<Trait> contents work?

我有这个最小的示例代码

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的善良人士发现我必须取消引用该框以获取内容,然后借用内容。 像这样

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) { }

它有效,但我不明白。

为什么我需要先取消引用? 想说什么错误? 通常,在函数结束时删除值不是错误。


显然不只是我不明白这是如何运作的; 已经提出了一个问题

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

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

重要的区别是向特征对象添加了+ 'static - 优先需要parens。

需要认识到的重要一点是&Foo中存在两个生命周期

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

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

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

在管道的另一端,我们有一个Box<Foo> 扩展了RFC的规则,这就变成了Box<Foo + 'static> 当我们借用它并尝试将其传递给函数时,我们有一个等式来解决:

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

Box将在块的末尾被删除,因此它肯定不是静态的。

具有明确的寿命的修复程序允许参考性状对象的生命周期从性状对象内部的参考文献的寿命不同。

如果您需要支持具有内部引用的特征对象,则替代方法是执行以下操作:

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

这个解释真正归功于nikomatsakis和他对GitHub的评论 ,我只是稍微扩展了一下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM