Rust从入门到实战系列二百零三:请求审核博文来改变其状态

本文描述了如何在Rust编程语言中为Post结构添加request_review方法,以实现状态转换,从Draft到PendingReview,以及StateTrait的使用,强调了所有权和状态模式在处理不同状态间的转换中的作用。
摘要由CSDN通过智能技术生成

接下来需要增加请求审核博文的功能,这应当将其状态由 Draft 改为 PendingReview。示例 17-15 展示
了这个代码:
文件名: src∕lib.rs

pub struct Post {

state: Option<Box>,

content: String,

}

impl Post {
// --snip–

pub fn new() -> Post {

Post {

state: Some(Box::new(Draft {})),

content: String::new(),

}

}

pub fn add_text(&mut self, text: &str) {

self.content.push_str(text);

}

pub fn content(&self) -> &str {

“”

}

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) -> Box;
}
struct Draft {}
impl State for Draft {
fn request_review(self: Box) -> Box {
Box::new(PendingReview {})
}
}
struct PendingReview {}
impl State for PendingReview {
fn request_review(self: Box) -> Box {
self
}
}
示例 17-15: 实现 Post 和 State trait 的 request_review 方法
这里为 Post 增加一个获取 self 可变引用的公有方法 request_review。接着在 Post 的当前状态下调
用内部的 request_review 方法,并且第二个 request_review 方法会消费当前的状态并返回一个新状态。
这里给 State trait 增加了 request_review 方法;所有实现了这个 trait 的类型现在都需要实现 request_review
方法。注意不同于使用 self、&self 或者 &mut self 作为方法的第一个参数,这里使用了 self : Box。
这个语法意味着该方法只可在持有这个类型的 Box 上被调用。这个语法获取了 Box 的所有权使老
状态无效化,以便 Post 的状态值可转换为一个新状态。
为了消费老状态,request_review 方法需要获取状态值的所有权。这就是 Post 的 state 字段中 Option
的来历:调用 take 方法将 state 字段中的 Some 值取出并留下一个 None,因为 Rust 不允许结构体实
例中存在值为空的字段。这使得我们将 state 的值移出 Post 而不是借用它。接着我们将博文的 state 值
设置为这个操作的结果。
我们需要将 state 临时设置为 None 来获取 state 值,即老状态的所有权,而不是使用 self .state = self .state.request_review();
这样的代码直接更新状态值。这确保了当 Post 被转换为新状态后不能再使用老 state 值。
Draft 的 request_review 方法需要返回一个新的,装箱的 PendingReview 结构体的实例,其用来代表
博文处于等待审核状态。结构体 PendingReview 同样也实现了 request_review 方法,不过它不进行任
何状态转换。相反它返回自身,因为当我们请求审核一个已经处于 PendingReview 状态的博文,它应该
继续保持 PendingReview 状态。
现在我们能看出状态模式的优势了:无论 state 是何值,Post 的 request_review 方法都是一样的。每个
状态只负责它自己的规则。
我们将继续保持 Post 的 content 方法实现不变,返回一个空字符串 slice。现在我们可以拥有 PendingReview
状态和 Draft 状态的 Post 了,不过我们希望在 PendingReview 状态下 Post 也有相同的行为。现在示例
17-11 中直到 10 行的代码是可以执行的!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值