[英]Why does moving a function to a default trait method introduce a borrowing error?
[英]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.