Skip to main content

PingCAP Talent-plan Project Diff - 1&2

· 5 min read

本文是在完成 PingCAP Talent-plan 中各个项目后与示例代码的对比报告。

Project 1

第一个 Project 内容不多,首先从kvs.rs可执行文件开始看,由于我最后将参数解析包从 clap 改成了 structopt,所以和示例代码就没什么可对比的了。而lib.rs部分,我的实现全部写在这个文件里了,而示例代码则是另建了一个文件作为模块引入,这也导致我的代码在后面的 Prokect 中越发混乱。在函数实现部分,get 函数有所不同,我使用了一个 match 而示例代码仅仅使用了一个函数,rust 有用的工具函数很多,也需要逐渐的积累。下面是代码对比。

match self.store.get(&key) {
Some(value) => Some(value.clone().to_owned()),
None => None,
}
// VS
self.map.get(&key).cloned()

Project 2

kvs.rs中示例代码依然使用 clap,可以明显的看出经过 structopt 的封装,代码会简洁很多。有一个值得注意的点是在参数无效时我的代码会 panic,而示例代码则是使用了unreachable macro后者同样会导致 panic,但是相比于panic macro可读性更强。 lib.rs部分首先提一个之前遇到的坑。我在早期代码中在HashMap::insert()函数后使用问号运算符导致编译器报错,指出自定义错误没有实现From<NoneError>而无论我如何修改代码都无法消除这个错误,经过查询发现关于 NoneError,docs.rs 上指出仍在 alpha,github 上面的相关 issue 还未关闭,再回头看了眼 talent-plan 开头所说的Practical Networked Applications in Rust is in an alpha state.我就有些害怕了。 虽然在最终的代码中我没有用到这个特性,但现在也对于这个实验特性有了一些了解:在本文编写时,std::option::NoneError结构体是一个仅在 nightly 分支支持的实验特性,它会在对Option<T>使用问号运算符并且值是 None 时产生,并且这个结构体没有实现Error triat。如果想要在自己的错误类型中实现From<NoneError>需要先将工具链修改为 nightly 然后显式启用该特性

#![feature(try_trait)]

下一个要提的就是结构化存储所用的结构体,现在再看代码我才我发现我在编写这个结构体时完全没有意识到自己在按 C 语言的逻辑设计结构,Rust 中的枚举结构是可以直接嵌套编写的,下面是代码对比

struct Cmd {
name: CmdName,
key: String,
value: Option<String>
}
enum CmdName {
Set
Rm
}
// VS
enum Command {
Set { key: String, value: String },
Remove { key: String },
}

这部分的主要逻辑是在实现命令的 log 存储和恢复,由于我实现的是单文件 log,而示例是多文件 log,在逻辑上不好做出对比,比较让我在意的一点是open(),由于这个函数需要支持两种类型的参数输入,所以我选择多编写一个函数来实现类型转换,但实际上 Rust 2018 的impl trait已经允许在参数表中声明函数需要实现的 triat 而非具体的类型了。换句话说,这个问题可以用多态解决。下面是示例代码的函数定义。

pub fn open(path: impl Into<PathBuf>) -> Result<KvStore>