[英]How to write a method that adds `self` as a mutable trait reference to a collection?
[英]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.