2017-03-31 36 views
0

我正在寫在鏽病一個簡單的遊戲,其包括Drawer,其被構造一次,然後通過許多方法作爲一個可變參考一個結構:使用含有借用參數

pub struct Drawer<'a> { 
    // ... 
    renderer: Renderer<'a>, 
    // ... 
} 

fn pause(drawer: &mut Drawer, events: &[Event]) { 
    // ... 
    drawer.draw_text(&TextPos::Centered, "Paused", 1); 
    // ... 
} 

我想重構我的代碼引入一個流暢的界面繪製文字,如:

drawer.text() 
    .size(4) 
    .centered() 
    .draw("Paused"); 

我通過創建一個TextDrawer結構這樣做,包含對Drawer參考:

pub struct TextDrawer<'a, 'b: 'a> { 
    pos: TextPos, 
    size: u32, 
    drawer: &'a mut Drawer<'b>, 
} 

impl<'a> Drawer<'a> { 
    pub fn text(&mut self) -> TextDrawer { 
     TextDrawer { 
      pos: TextPos::At(0, 0), 
      size: 1, 
      drawer: self, 
     } 
    } 
} 

我認爲我放在結構上的生命週期是正確的(參考必須持續,只要Drawer本身)。

但是,我的text方法不會編譯,直到我添加明確的生命週期。當我這樣做時,每個調用text的方法都需要明確的生命週期,等等。我很驚訝這些生活必須說明:畢竟,他們的形式都是fn foo<'a, 'b: 'a>(drawer: &mut'a Drawer<'b>)。在此之前,我曾假設這已經是推測的壽命,因爲它始終需要持續的時間,只要它本身就是Drawer

是否有必要把這些明確的生命期所有其他我的方法簽名?或者我能否以其他方式避免它?

+2

與您的問題無關,但您可能會考慮將'Drawer'重命名爲沒有更常見第二個含義的東西。至少,假設它的發音是/drɔər/而不是/ dror/ – trentcl

+0

你能發佈你的錯誤嗎?你發佈的內容看起來並不像它會編譯的。 TextDrawer的返回可能會導致錯誤的界限,但這並不明確。 '抽屜:&'一個抽屜<'b>'看起來不對,因爲你不需要對內部類型進行改變(可變性由對類型的引用繼承,並且當引用對象時,所有內容都是可變的) 。 – bluejekyll

+1

@bluejekyll你最後的陳述是錯誤的:你不能通過'&mut&T'(對不可變引用的可變引用)改變任何東西。所以裏面的可變引用確實有意義(除非我在這裏缺少重要的東西)。 –

回答

1

感謝上面Lukas製作的minimal example,我意識到我只是簡單地將我的text方法的生命週期參數向後取。

我的不正確壽命:

impl<'a> Drawer<'a> { 
    pub fn text<'b>(&'b mut self) -> TextDrawer<'a, 'b> { 
     // omitted 
    } 
} 

正確的壽命:

impl<'a> Drawer<'a> { 
    pub fn text<'b>(&'b mut self) -> TextDrawer<'b, 'a> { 
     // omitted 
    } 
} 

在此之後,編譯沒有任何進一步的明確的壽命。