Rust 如何将可变的自我引用传递给trait方法?

Rust 如何将可变的自我引用传递给trait方法?,rust,Rust,在阅读《铁锈书》(第二版)的过程中,我承担了可选任务,为以下结构实现方法add_text pub struct Post { state: Option<Box<State>>, content: String, } 我的问题是,为了从我的post结构中获取状态来调用添加文本方法,我不可更改地借用self(在post)并且不能传递对状态特征的添加文本方法的可变引用: impl Post { // snip pub fn add_text

在阅读《铁锈书》(第二版)的过程中,我承担了可选任务,为以下结构实现方法
add_text

pub struct Post {
    state: Option<Box<State>>,
    content: String,
}
我的问题是,为了从我的post结构中获取
状态
来调用
添加文本
方法,我不可更改地借用
self
(在
post
)并且不能传递对
状态
特征的
添加文本
方法的可变引用:

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
的可变引用,否则我无法更改它的文本。另一方面,我需要首先获取
状态
,否则我甚至无法调用该方法


解决这个问题的一种方法是将
add_text
更改为
get_text\u to_add
,这不需要
Post
的可变性,但是我想确保我没有监督解决这个问题的任何选项。

使用structs Rust足够聪明,可以进行不相交的借用,因此您不需要传递对整个
Post
结构的可变引用,只需修改其中的一部分(在本例中为内容)


这应该行得通,但感觉有点强迫(正如EvilTak指出的那样,在
Draft::add_text
中对self的引用是多余的)。我想这是练习的一部分重点;虽然可以在Rust中从OOP实现某些模式,但有更好的方法来建模问题。

在我看来,这就像是一种代码味道。首先,
State::add_text
方法impl on
Draft
Draft
结构没有任何关系-您最好删除
&self
参数并完成它。其次,作为这个假设库的外部使用者,我希望
add_text
方法位于
Post
结构本身。您最好将
添加文本
移动到
帖子
,并根据需要查找信息或修改
状态
字段。如果你只想
add_text
如果文章是草稿,你可以检查
self.state
是否是
draft
内部
post::add_text
。谢谢,我没有想到过这种方法。我同意你和@EvilTak的观点,这很可能是一种不好的方式(因此,我的问题的最后一段)。另一方面,这是一个很好的机会来学习更多关于借贷的知识,所以谢谢你在这方面的帮助。我将在星期一接受答复。
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
    }
}
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);  
    }
}