簡體   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