Dan*_*ker 12 traits rust borrow-checker
我有这个最小的示例代码:
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) { }
Run Code Online (Sandbox Code Playgroud)
但它失败了这个错误:
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
Run Code Online (Sandbox Code Playgroud)
#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) { }
Run Code Online (Sandbox Code Playgroud)
它有效,但我不明白.
为什么我需要先取消引用?想说什么错误?通常,在函数结束时删除值不是错误.
让我们从允许代码工作的更改开始:
fn encrypt(encryptor: &mut (Foo + 'static)) { }
Run Code Online (Sandbox Code Playgroud)
重要的区别是添加+ 'static到特征对象 - 优先需要的是parens.
认识到最重要的事情是,有有2个寿命呈现&Foo:
&'a Foo&(Foo + 'b).如果我正确地读取RFC,这是由RFC 192引入的,RFC 599指定了生命周期的合理默认值.在这种情况下,生命周期应该扩展如下:
fn encrypt(encryptor: &mut Foo) { }
fn encrypt<'a>(encryptor: &'a mut (Foo + 'a)) { }
Run Code Online (Sandbox Code Playgroud)
在管道的另一端,我们有一个Box<Foo>.通过RFC的规则扩展,这变成了Box<Foo + 'static>.当我们借用它并尝试将其传递给函数时,我们有一个等式来解决:
'static.'static.哦哦!在Box将在块的结尾被丢弃所以它肯定不是一成不变的.
具有明确的寿命的修复程序允许基准的寿命到该性状对象从引用的寿命不同内部性状对象.
如果您需要支持具有内部引用的特征对象,则替代方法是执行以下操作:
fn encrypt<'a>(encryptor: &mut (Foo + 'a)) { }
Run Code Online (Sandbox Code Playgroud)
这个解释真正归功于nikomatsakis和他对GitHub的评论,我只是稍微扩展了一下.
| 归档时间: |
|
| 查看次数: |
1029 次 |
| 最近记录: |