Rust - 错误处理

Rust - 错误处理 首页 / Rust入门教程 / Rust - 错误处理

在Rust中,错误可以分为两大类,如下表所示。

Name & 描述Usage

Recoverable

可恢复的错误

Result enum

UnRecoverable

无法恢复的错误

panic macro

与其他编程语言不同,Rust没有Exception异常,它返回可恢复错误的枚举Result <T,E>,如果程序遇到不可恢复的错误,则调用panic宏。

Panic宏

panic!宏允许程序立即终止并向程序调用者提供反馈,当程序达到不可恢复的状态时,应使用它。

fn main() {
   panic!("Hello");
   println!("End of main"); //无法执行
}

在上面的示例中,程序在遇到 panic!宏时将立即终止。

thread 'main' panicked at 'Hello', main.rs:3

Panic!宏操作

fn main() {
   let a=[10,20,30];
   a[10]; //由于无法到达索引 10
}
warning: this expression will panic at run-time
--> main.rs:4:4
  |
4 | a[10];
  | ^^^^^ index out of bounds: the len is 3 but the index is 10

$main
thread 'main' panicked at 'index out of bounds: the len 
is 3 but the index is 10', main.rs:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.

一个程序可以引起panic!宏,如下例所示-

fn main() {
   let no=13; 

   if no%2 == 0 {
      println!("Thank you , number is even");
   } else {
      panic!("NOT_AN_EVEN"); 
   }
   println!("End of main");
}

如果分配给变量的值是奇数,则上面的示例将返回错误。

thread 'main' panicked at 'NOT_AN_EVEN', main.rs:9
note: Run with `RUST_BACKTRACE=1` for a backtrace.

输出枚举

枚举结果 - <T,E>可用于处理可恢复的错误,它有两个变体-OK和Err,T和E是通用类型参数,T表示在OK变量中成功情况下将返回的值的类型,E表示在Err变量中失败情况下将返回的错误的类型。

enum Result<T,E> {
   OK(T),
   Err(E)
}

让我们借助示例了解这一点-

use std::fs::File;
fn main() {
   let f=File::open("main.jpg"); 
   //此文件不存在
   println!("{:?}",f);
}

如果文件已经存在,则程序返回 OK(File),如果找不到文件,则返回 Err(Error)。

Err(Error { repr: Os { code: 2, message: "No such file or directory" } })

现在让我们看看如何处理Err变体。

以下示例处理使用 match 语句打开文件时返回的错误

use std::fs::File;
fn main() {
   let f=File::open("main.jpg");   //main.jpg 不存在
   match f {
      Ok(f)=> {
         println!("file found {:?}",f);
      },
      Err(e)=> {
         println!("file not found\n{:?}",e);   //出错
      }
   }
   println!("end of main");
}

注意-尽管未找到文件,程序仍会打印 main 事件的 end 。这意味着程序已正常处理错误。

file not found
Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }
end of main

输出枚举示例

如果数字不是偶数,则 is_even 函数将返回错误, main()函数处理此错误。

fn main(){
   let result=is_even(13);
   match result {
      Ok(d)=>{
         println!("no is even {}",d);
      },
      Err(msg)=>{
         println!("Error msg is {}",msg);
      }
   }
   println!("end of main");
}
fn is_even(no:i32)->Result<bool,String> {
   if no%2==0 {
      return Ok(true);
   } else {
      return Err("NOT_AN_EVEN".to_string());
   }
}

注意-由于main函数可以正常处理错误,因此会打印 main 语句的 end 。

Error msg is NOT_AN_EVEN
end of main

unwrap()和Expect()

标准库包含两个枚举的两个助手方法-Result <T,E>和Option <T>实现,您可以使用它们来简化错误情况,在这些情况下,您实际上并不希望失败。如果方法成功,则使用“expect"函数提取结果。

Sr.NoMethodSignature & Remark
1unwrap

unwrap(self):T

期望self是Ok/Some并返回其中包含的值,如果它是 Err 或 None ,则会引发错误并显示错误内容。

2expect

expect(self, msg: &str): T

行为就像解包一样,除了它会在错误内容之前输出自定义消息。

无涯教程网

unwrap() 函数

unwrap()函数返回操作成功的实际结果,如果操作失败,它将返回带有默认错误消息的紧急消息,此函数是match语句的简写。

fn main(){
   let result=is_even(10).unwrap();
   println!("result is {}",result);
   println!("end of main");
}
fn is_even(no:i32)->Result<bool,String> {
   if no%2==0 {
      return Ok(true);
   } else {
      return Err("NOT_AN_EVEN".to_string());
   }
}
result is true
end of main

修改上面的代码,将一个奇数传递给 is_even()函数。

链接:https://www.learnfk.comhttps://www.learnfk.com/rust/rust-error-handling.html

来源:LearnFk无涯教程网

unwrap()函数将出现错误并返回默认错误消息,如下所示

thread 'main' panicked at 'called `Result::unwrap()` on 
an `Err` value: "NOT_AN_EVEN"', libcore\result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace

expect() 函数

如果出现紧急情况,程序可以返回自定义错误消息。这在以下示例中显示-

use std::fs::File;
fn main(){
   let f=File::open("pqr.txt").expect("File not able to open");
   //file does not exist
   println!("end of main");
}

函数Expect()与unwrap()类似,唯一的区别是可以使用期望显示自定义错误消息。

thread 'main' panicked at 'File not able to open: Error { repr: Os 
{ code: 2, message: "No such file or directory" } }', src/libcore/result.rs:860
note: Run with `RUST_BACKTRACE=1` for a backtrace.

祝学习愉快!(内容编辑有误?请选中要编辑内容 -> 右键 -> 修改 -> 提交!)

技术教程推荐

Go语言从入门到实战 -〔蔡超〕

从0开始做增长 -〔刘津〕

大规模数据处理实战 -〔蔡元楠〕

深入浅出计算机组成原理 -〔徐文浩〕

即时消息技术剖析与实战 -〔袁武林〕

.NET Core开发实战 -〔肖伟宇〕

手机摄影 -〔@随你们去〕

深入C语言和程序运行原理 -〔于航〕

AI大模型企业应用实战 -〔蔡超〕

好记忆不如烂笔头。留下您的足迹吧 :)