如题,代码如下:
pub struct Post {
state: Option<Box<dyn State>>,
content: String,
}
impl Post {
// --snip--
pub fn request_review(&mut self) {
if let Some(s) = self.state.take() {
self.state = Some(s.request_review())
}
}
}
trait State {
fn request_review(self: Box<Self>) -> Box<dyn State>;
}
struct Draft {}
impl State for Draft {
fn request_review(self: Box<Self>) -> Box<dyn State> {
Box::new(PendingReview {})
}
}
struct PendingReview {}
impl State for PendingReview {
fn request_review(self: Box<Self>) -> Box<dyn State> {
self
}
}
关于这段代码:
pub fn request_review(&mut self) {
if let Some(s) = self.state.take() {
self.state = Some(s.request_review())
}
}
教程上说:
我们需要将 state 临时设置为 None 来获取 state 值,即老状态的所有权,而不是使用 self.state = self.state.request_review(); 这样的代码直接更新状态值。这确保了当 Post 被转换为新状态后不能再使用老 state 值。
虽然教程上有做说明,但是我还是不能理解这里为什么是 “确保了当 Post 被转换为新状态后不能再使用老 state 值” , 麻烦再帮忙给解释解释,谢谢。
在是状态模式嘛……可能和整个代码未来要实现的逻辑有关,也可能是考虑并发时的情况?
单从代码上看是这样的:
if let Some(s) = self.state.take()
这一句执行的时候,self.state
的所有权被转移到了s
上,所以此时self.state
已经是None
了。于是,在这个
if let
作用域中,包括之后的代码里,self.state
不再拥有旧值,因为旧值的所有权已经在s
上了。而如果使用
self.state = self.state.request_review();
直接赋值,则在这个赋值的过程中,request_review()
返回之前,self.state
依然是旧值。