gpt4 book ai didi

rust - 借用 Box 内容如何工作?

转载 作者:行者123 更新时间:2023-11-29 07:42:52 26 4
gpt4 key购买 nike

我有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 .

最佳答案

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

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

重要的区别是添加了 + 'static到 trait 对象 - parens 只需要优先级。

重要的是要认识到are two lifetimes present in &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将在 block 的末尾删除,因此它肯定不是静态的。

具有显式生命周期的修复允许特征对象的引用的生命周期不同于内部特征对象的引用的生命周期。

如果您需要使用内部引用来支持特征对象,另一种方法是执行以下操作:

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

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

关于rust - 借用 Box<Trait> 内容如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41682820/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com