簡體   English   中英

如何將可變自引用傳遞給特征方法?

[英]How to pass a mutable self reference on to a trait method?

在完成Rust書的OOP-Chapter (第2版)的過程中,我接受了可選任務來實現以下struct的方法add_text

pub struct Post {
    state: Option<Box<State>>,
    content: String,
}

有三個結構實現了State特性,但只有Draft結構應該實際執行某些操作。 我實現如下

trait State {
    // snip
    fn add_text(&self, post: &mut Post, text: &str) { }
}


struct Draft { }

impl State for Draft {
    // snip
    fn add_text(&self, post: &mut Post, text: &str) {
        post.content.push_str(text);
    }
}

我的問題是,為了讓我的post結構中的State調用add_text方法,我add_text借用self (在Post )並且不能傳遞對State trait的add_text方法的可變引用:

impl Post {
    // snip

    pub fn add_text(&mut self, text: &str){
        let state = self.state.as_ref().unwrap();  // This immutably borrows self
        state.add_text(self, text);  // so that this mutable borrow is no longer possible
    }
}

我該如何應對這種困境? 我絕對需要一個對Post的可變引用,否則我無法改變它的文本。 另一方面,我需要先獲得State ,否則我甚至無法調用該方法。

解決這個問題的一種方法是將add_text更改為get_text_to_add ,這不需要Post可變性,但我想確保我不監督任何解決此問題的選項。

使用結構Rust非常聰明,能夠進行不相交的借用,因此您不需要將可變引用傳遞給整個Post結構,只需要修改它的一部分(在本例中為內容)。

trait State {
    // snip

    // Modify the method on the add_text trait so that it
    // takes a mutable reference to String
    fn add_text(&self, content: &mut String, text: &str) { }
}

struct Draft { }

impl State for Draft {
    // snip

    // Update the implementation of State for Draft so that it
    // matches the new signature
    fn add_text(&self, content: &mut String, text: &str) {
        content.push_str(text);
    }
}

impl Post {
    // snip

    pub fn add_text(&mut self, text: &str){
        let state = self.state.as_ref().unwrap();  

        // Now when you call add_text you don't require a mutable 
        // reference to self, just to self.content and so the 
        // borrow checker is happy
        state.add_text(&mut self.content, text);  
    }
}

這應該有效,但感覺有點強迫,(因為EvilTak指出在Draft::add_text對self的引用是多余的)。 我想這是演習的一部分; 雖然可以從Rust中的OOP實現某些模式,但有更好的方法可以對問題進行建模。

暫無
暫無

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

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