在学习Rust 书(第二版)的OOP 章节时,我承担了实现add_text以下结构的方法的可选任务
pub struct Post {
state: Option<Box<State>>,
content: String,
}
Run Code Online (Sandbox Code Playgroud)
有三个结构体实现了该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);
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,为了State从我的 post 结构中调用该add_text方法,我一成不变地借用了self( in Post),并且无法传递对add_text特征方法的可变引用State:
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
}
}
Run Code Online (Sandbox Code Playgroud)
我该如何应对这个困境?我绝对需要对 的可变引用Post,否则我无法更改其文本。另一方面,我需要获得第State一个,否则我什至无法调用该方法。
解决此问题的一种方法是更改add_text为get_text_to_add不需要 的可变性Post,但我想确保我不会监督任何解决此问题的选项。
小智 4
对于结构,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);
}
}
Run Code Online (Sandbox Code Playgroud)
这应该可行,但感觉有点强迫(因为 EvilTak 指出对 self 的引用Draft::add_text是多余的)。我想这就是练习的重点之一;虽然可以在 Rust 中实现 OOP 的某些模式,但还有更好的方法来对问题进行建模。
| 归档时间: |
|
| 查看次数: |
3842 次 |
| 最近记录: |