Skip to main content

PingCAP Talent-plan Project Diff - 1&2

· One 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,}// VSself.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}// VSenum 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>