簡體   English   中英

在“ get_trait_mut”中返回對特征的可變引用

[英]Returning mutable reference to trait in “get_trait_mut”

考慮以下:

pub trait Inner {}

pub struct Thing<'a> {
    inner: &'a Inner,
}

impl<'a> Thing<'a> {
    pub fn get_inner(&self) -> &Inner {
        self.inner
    }

    pub fn get_inner_mut(&mut self) -> &mut Inner {
        &mut self.inner
    }
}

導致:

error[E0277]: the trait bound `&'a (dyn Inner + 'a): Inner` is not satisfied
  --> src/lib.rs:13:9
   |
13 |         &mut self.inner
   |         -^^^^^^^^^^^^^^
   |         |
   |         the trait `Inner` is not implemented for `&'a (dyn Inner + 'a)`
   |         help: consider removing 1 leading `&`-references
   |
   = note: required for the cast to the object type `dyn Inner`

哪個是公平的,所以讓我們遵循建議吧?

與上述相同,但有以下更改:

pub fn get_inner_mut(&mut self) -> &mut Inner {
    mut self.inner
}
error: expected expression, found keyword `mut`
  --> src/lib.rs:13:9
   |
13 |         mut self.inner
   |         ^^^ expected expression

(找到的關鍵字mut是我的本地編譯器所說的,盡管不是下面的“游樂場”鏈接中的那個!)

嗯,有道理吧? mut並不是一個表達式

但是如何返回可變的引用呢?

好吧,讓我們開始嘗試吧?

pub fn get_inner_mut(&mut self) -> &mut &Inner {
    &mut &self.inner
}

(注意,更改了簽名!)

導致:

error[E0308]: mismatched types
  --> src/lib.rs:13:9
   |
13 |         &mut &self.inner
   |         ^^^^^^^^^^^^^^^^ lifetime mismatch
   |
   = note: expected type `&mut &dyn Inner`
              found type `&mut &'a (dyn Inner + 'a)`
note: the anonymous lifetime #1 defined on the method body at 12:5...
  --> src/lib.rs:12:5
   |
12 | /     pub fn get_inner_mut(&mut self) -> &mut &Inner {
13 | |         &mut &self.inner
14 | |     }
   | |_____^
note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 7:6
  --> src/lib.rs:7:6
   |
7  | impl<'a> Thing<'a> {
   |      ^^

僅指定生存期就可以解決所有問題嗎?

這是操場

我看到的主要問題是Thing僅對inner具有不變的引用。

這是我對此的看法:

pub trait Inner {}

pub struct Thing<'a> {
    inner: &'a mut Inner,
}

impl<'a> Thing<'a> {
    pub fn get_inner(&self) -> &Inner {
        self.inner
    }

    pub fn get_inner_mut(&mut self) -> &mut Inner {
        &mut *self.inner
    }
}

struct SomeInner {}

impl Inner for SomeInner {}

fn main() {
    let mut inner = SomeInner {};
    let mut thing = Thing { inner: &mut inner };

    let inner: &Inner = thing.get_inner();
    let mutable_inner: &mut Inner = thing.get_inner_mut();
}

它會編譯(您可以在操場上驗證)

注意

  • let mut inner = SomeInner {} -> inner是可變的
  • let mut thing -> thing也是可變的
  • &mut *self.shape >我正在取消引用,然后再次創建對其的可變引用

我相信會有更完善的解決方案,希望其他人也能提供幫助。

編輯 :正如Shepmaster所指出的那樣,根本不需要編寫&mut *self.shape 由於我們已經可以訪問可變引用,因此僅返回self.inner就足夠了-編譯器將確保self.inner可變性。

最后,我的嘗試將變成:

impl<'a> Thing<'a> {
   pub fn get_inner(&self) -> &Inner {
     self.inner
   }

   pub fn get_inner_mut(&mut self) -> &mut Inner {
      self.inner
   }
}

操場上的完整例子

暫無
暫無

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

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