前两天看了一个在 rustlang 中如何利用 generic 和 PhantomData 来让我们的 api 更加合理的视频, 当时看完就想写一篇相关内容的文章, 但是没有立即动手,一推迟,不出意外的忘了。这两天又接手了一个半成品的项目, 需要维护原有代码和添加新的特性, 看代码的时候感慨良多, 又想起了前两天看的那个视频, 觉得必须得写点什么了。
假设我们要创建一个密码管理器, 这个管理器有两种状态, 一种是锁定状态, 在锁定状态下我们可以添加新的密码; 一种是非锁定状态, 在非锁定状态下我们可以列出所有的密码; 在任何状态下, 我们都可以查看管理器的版本。
代码如下:
use std::collections::HashMap;
#[derive(Debug, Eq, PartialEq)]
enum State {
Locked,
Unlocked,
}
struct PasswordManager {
state: State,
passwords: HashMap<String, String>,
version: String,
}
impl PasswordManager {
fn new(version: &str) -> Self {
Self {
state: State::Unlocked,
passwords: HashMap::new(),
version: version.into(),
}
}
fn lock(&mut self) -> Result<(), String> {
if self.state == State::Locked {
return Err("cannot lock a locked manager".into());
}
self.state = State::Locked;
Ok(())
}
fn unlock(&mut self) -> Result<(), String> {
if self.state == State::Unlocked {
return Err("cannot unlock a unlocked manager".into());
}
self.state = State::Unlocked;
Ok(())