admin 管理员组

文章数量: 887021

Rust

这篇文章收录于Rust 实战专栏。这个专栏中的相关代码来自于我开发的笔记系统。它启动于是2023年的9月14日。相关技术栈目前包括:Rust,Javascript。关注我,我会通过这个项目的开发给大家带来相关实战技术的分享。


我们写的代码主要有两部分,第一部分是正常的业务流程,第二部分是错误处理。 通常情况下,这两部分代码不是分开的,而是杂糅在一起的。 这让我们后期维护正常的业务逻辑非常头疼。

今天分享的是Rust语言中的错误处理的魔法, 它可以帮助我们写代码时,将错误处理的“体积”压缩到最小,同时还保证错误分支能被一个剩的处理掉。


例子代码

pub async fn insert_or_update_note(note: &Note, client: &Client) -> Result<String, MyError> {let id: String = if note.has_id() {note.id.clone()} else {gen_uuid()};if note.has_id() {let _ = client.execute("update notes set ...",&[...],).await?;} else {let _ = client.execute("insert into notes ...",&[...],).await?;}Ok(id)
}

上面的代码直接关注的是业务逻辑的表达,要说错误处理部分,除了"?",就没有别的了。这就是我所说的魔法。如何应用这个魔法,使其为代码的可维护性发挥最大作用呢?

蓝图


首先,为我们的项目定义一个统一的错误类型MyError,实际上就是实现std::convert::From<T> trait。我们当然没有必要为每一种外部crate的错误类型去实现一次From<T>
这里面的关键要素是derive_more::{From},它直接实现了外部错误类型向MyError的转换。而在我们的业务代码中,借助"?"语法,通过Rust编译器,神不知鬼不觉地就完成了错误分支的处理。
如果后续的代码维护中又加入了新的错误类型,直接向MyError里面增加对应的枚举值就可以了。是不是很方便啊?

总结

我们充分利用了Rust语言的关注点分离的语法特性,借助derive_more::From,实现了错误类型的魔法转换。这对代码的可维护性来说,是一个价值不小的优化。

最后,欢迎大家留言交流。关注我,后面会在Rust 实战专栏中给大家带来更多关于Rust开发实战的分享。

本文标签: Rust