![](/img/trans.png)
[英]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.