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 onDraft
与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);
}
}