Rust中的异常处理方式

目录
⭐ 前言
⭐ 环境搭建
🔷 Rust+Cargo安装
⭐ 异常
🔷不可恢复异常
🔶主动触发
🔶被动触发
🔷可恢复异常
🔷自定义异常
📚 学Rust推荐资料
⭕总结
欢迎来到 盹猫(>^ω^<)的博客
本篇文章主要介绍了
[Rust中的异常处理方式]
❤博主广交技术好友,喜欢文章的可以关注一下❤
⭐ 前言
在各种编程语言中,异常处理都是绕不开的话题,我们都需要自己捕获一些可以预测到的异常以进行友好的抛出异常并记录日志。在语言Rust中同样需要进行异常的抛出,但他并像不通过try/catch进行进行异常捕获,而是通过 Result 枚举 处理可恢复错误,通过 panic! 宏 处理不可恢复错误(类似其他语言的 “异常”,但设计理念不同)。
本篇文章就让我们走进Rust的异常处理工厂,详细了解Rust在处理异常时的具体步骤。
Let's GO!
⭐ 环境搭建
🔷 Rust+Cargo安装
在Rust代码开发时,一般使用Cargo对项目的生命周期进行管理(类似于Java项目中maven依赖),官网提供了官方的Cargo安装方法,如果你是Linux系统可以使用以下命令进行安装:‘
curl https://sh.rustup.rs -sSf | sh
当然为方便使用,我这边也创建了一个脚本库,也可以使用以下命令使用脚本进行安装:
# 下载脚本
curl -O https://install.nodcat.com/shell/rust_install.sh# 赋予执行权限
chmod +x rust_install.sh# 运行脚本(不推荐使用root用户)
./rust_install.sh
如果你是Windows系统,需要下载rustup-init.exe 文件进行运行安装。
安装完成后使用下述命令创建一个新的项目:
cargo new 项目名
⭐ 异常
🔷不可恢复异常
🔶主动触发
在Rust中通常通过 panic! 宏 处理不可恢复错误,只是简单的抛出异常,类似与Java中的assert抛出异常:
fn main() {let age = 17;if age <18 {panic!("年龄不能小于18");}}
🔶被动触发
Rust 内置机制在遇到严重错误时自动触发,如发生数组访问的越界:
fn main() {let v = vec![1, 2, 3];println!("{}", v[10]);
}
🔷可恢复异常
可恢复异常使用Result枚举来处理异常,Rusult有两个枚举变体,分别是正常情况下的返回Ok和异常状态下的Err返回:
enum Result<T, E> {Ok(T), // 成功:包含返回值 TErr(E), // 失败:包含错误信息 E
}
⚠️注意:在 Rust 的 Result<T, E> 枚举定义中,Ok(T) 和 Err(E) 既不是参数也不是方法,而是枚举的变体(Variant)。可以理解为枚举类型的 “可能取值”,每个变体可以携带关联的数据。
Rust中有很多可能会发生异常的方法,都会以Result枚举的方式返回,以便开发者对后续的异常进行处理,例如文件读取操作:
fn main() {let result = read_file("test.txt");match result {Ok(file) => println!("文件打开成功: {:?}", file),Err(e) => println!("文件打开失败: {}", e), // 处理错误}
}
这里的result是Result枚举,所以可以通过match来进行打开成功读取或失败时的异常捕获。
🔷自定义异常
有时我们需要创建自定义的异常,以实现自定义的错误输出。如:在将字符串转换为struct时,我们希望当缺少字段时进行报错,可以使用以下方法定义一个错误枚举:
#[derive(Debug)]
pub enum UserParseError {MissingUsername,MissingPassword,
}
但要注意,这时的枚举只是个枚举,它不能被成为异常。要实现异常我们需要让该枚举实现Rust提供的Error这个Trait,如下:
impl Error for UserParseError {}
这时就可以将UserParseError作为异常使用了,但如果我们像自定义异常输出,我们需要再实现Display这个Trait,以对产生不同的错误时,打印不同的消息提示:
impl Display for UserParseError {fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {match self {//当是缺少用户名异常时,打印username is missingUserParseError::MissingUsername => write!(f, "username is missing"),//当是缺少密码异常时,打印password is missingUserParseError::MissingPassword => write!(f, "password is missing"),}}
}
使用方法如下:
当将“zhangsan,123”转换为User类型时,如果分割时缺少用户名,报出UserParseError::MissingUsername 异常
impl TryFrom<String> for User {type Error = UserParseError;fn try_from(value: String) -> Result<Self, Self::Error> {let mut split = value.split(",");let username = split.next().ok_or(UserParseError::MissingUsername)?;let password = split.next().ok_or(UserParseError::MissingPassword)?;Ok(User {username: username.to_string(),password: password.to_string(),})}
}
我们使用下述代码去调用该TryFrom方法:
fn main() {let c = String::from("");let user: Result<User, UserParseError> = c.try_into();match user {Ok(u) => println!("User created: {:?}", u),Err(e) => println!("Error creating user: {:?}", format!("{}", e)),}
}
这时控制台就会打印我们自定义的异常信息了,效果如下:

📚 学Rust推荐资料
Rust语言圣经(开源非常推荐)
Rust官方文档(官方权威翻译文档)
⭕总结
通过文章可以看出,Rust在设计时提供了很好的异常处理机制。通过不可恢复异常,捕获一些系统性的错误和开发时进行快速代码测试,通过可恢复的异常Result,又可以保证程序的稳定性和自定义异常时的高扩展性。
由此可以看出,Rust在设计时还是非常用心的,也希望Rust社区可以发展并越来越强大。
上面就是所有文章内容了,如果内容对你有帮助,麻烦留一个赞👍和收藏⭐支持一下!
如果你对区块链内容感兴趣可以查看我的专栏:小试牛刀-区块链
感谢您的关注和收藏!!!!!!
