簡體   English   中英

如何返回對存儲在struct成員中的Optional boxed Trait的可變引用

[英]How do I return a mutable reference to an Optional boxed Trait stored in a struct member

我的目標是返回對存儲在Box中的特征對象的可變引用。

這似乎與有關借用對可選struct成員的引用的問題有關 ,但是主要區別似乎在於trait對象的存在。 我也試圖返回一個選項而不是結果。

嘗試使用相同的方法似乎會導致終身問題。

樣例代碼:

trait Baz {}

#[derive(Debug)]
struct Foo;

impl Baz for Foo {}

struct Bar {
    data: Option<Box<Baz>>,
}

enum BarErr {
    Nope,
}

impl Bar {
    fn borrow_mut(&mut self) -> Option<&mut Baz> {
        self.data.as_mut().map(|x| &mut **x)
    }
}

游樂場鏈接。

錯誤信息:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/lib.rs:20:9
   |
20 |         self.data.as_mut().map(|x| &mut **x)
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
   |
   = note: expected type `std::option::Option<&mut dyn Baz>`
              found type `std::option::Option<&mut (dyn Baz + 'static)>`
note: the anonymous lifetime #1 defined on the method body at 19:5...
  --> src/lib.rs:19:5
   |
19 | /     fn borrow_mut(&mut self) -> Option<&mut Baz> {
20 | |         self.data.as_mut().map(|x| &mut **x)
21 | |     }
   | |_____^
   = note: ...does not necessarily outlive the static lifetime

我真的看不到壽命會在哪里延長。

另外嘗試用as_mut替換&mut **x也無濟於事。

發生這種情況是由於編譯器中有一個怪癖。 讓我們擴展borrow_mut的生存期:

fn borrow_mut<'a>(&'a mut self) -> Option<&'a mut dyn Baz> {

表達方式

self.data.as_mut().map(|x| &mut **x)

推斷類型為Option<&mut dyn (Baz + 'static)> ,而函數期望輸出Option<&'a mut dyn (Baz + 'a)> 應用於特征對象的生命周期約束的這種細微差別無法通過強制轉換解決,因為可變引用相對於特征對象的生命周期是不變的。

我們可以做的就是同意輸出對dyn Baz + 'static的可變引用:

fn borrow_mut<'a>(&'a mut self) -> Option<&'a mut (dyn Baz + 'static)> {
   self.data.as_mut().map(|x| x.as_mut())
}

或者告訴編譯器通過其他方式(例如,使用手動match語句? Option<&'a mut (dyn Baz + 'a)>將表達式解析為Option<&'a mut (dyn Baz + 'a)> ? 運算符或演員表。

impl Bar {
    fn borrow_mut(&mut self) -> Option<&mut dyn Baz> {
        self.data.as_mut().map(|x| &mut **x as &mut dyn Baz)
    }
}

另請參閱: Rust中Box類型的協方差

似乎使用解構語法似乎可以解決此問題:以下代碼可以正常編譯:

fn borrow_mut(&mut self) -> Option<&mut Baz> {
    match &mut self.data {
        Some(e) => Some(e.as_mut()),
        None => None,
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM