学习Rust教程有关Option<T>的疑问?
如题,代码如下:
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 值” , 麻烦再帮忙给解释解释,谢谢。
回复
1个回答

test
2024-07-17
在是状态模式嘛……可能和整个代码未来要实现的逻辑有关,也可能是考虑并发时的情况?
单从代码上看是这样的:
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
依然是旧值。
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容