在阅读Rust书籍(第二版)的OOP-Chapter时,我尝试实现以下结构体的可选方法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方法,我需要对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
进行可变性,但我想确保我没有忽略任何解决此问题的选项。
Draft
上的State::add_text
方法实现与Draft
结构体完全没有关系 - 你可以删除&self
参数并完成它。其次,作为这个假想库的外部使用者,我期望add_text
方法在Post
结构体本身上。将add_text
移动到Post
中,并根据需要查找信息或改变state
字段会更好。如果您只想在帖子是草稿时添加文本,则可以在Post::add_text
中检查self.state
是否为Draft
。 - EvilTak