31.错误处理.rs

/*
程序中一般会出现两种错误:可恢复错误和不可恢复错误
可恢复错误:可恢复错误的典型案例是文件访问错误,如果访问一个文件失败,有可能是因为它正在被占用,是正常的,我们可以通过等待来解决
不可恢复错误:由编程中无法解决的逻辑错误导致的,例如访问数组末尾以外的位置
对于可恢复错误用 Result<T, E> 类来处理,对于不可恢复错误使用 panic! 宏来处理。
enum Result<T, E> {
    Ok(T),
    Err(E),
}
在 Rust 标准库中可能产生异常的函数的返回值都是 Result 类型的

*/

use std::fs::File;
use std::io;
use std::io::Read;

fn main() {
     //不可恢复错误用法:
     //panic!("error occured");

     let f = File::open("hello.txt");
     match f {
          Ok(file) => {
               println!("File opened successfully.");
          }
          Err(err) => {
               println!("Failed to open the file.");
          }
     }

     //如果想使一个可恢复错误按不可恢复错误处理,Result 类提供了两个办法:unwrap() 和 expect(message: &str) :
     //两者的区别在于 expect 能够向 panic! 宏发送一段指定的错误信息。
     let f1 = File::open("hello.txt").unwrap();
     let f2 = File::open("hello.txt").expect("Failed to open.");

     //测试方法1
     let r = myerro(-10000);
     if let Ok(v) = r {
          println!("Ok: f(-1) = {}", v);
     } else {
          println!("Err");
     }

     //测试方法2
     println!("{:?}", call_myerro(-101));

     //测试方法3
     println!("{:?}", call_myerro2(101));

     catch_ifreadfile_err();
}

//自定义错误
fn myerro(i: i32) -> Result<i32, bool> {
     if i >= 0 {
          Ok(i)
     } else {
          Err(false)
     }
}

//测试-自定义错误
fn call_myerro(i: i32) -> Result<i32, bool> {
     let t = myerro(i);
     return match t {
          Ok(i) => Ok(i),
          Err(b) => Err(b),
     };
}

//call_myerro写有些冗长,Rust 中可以在 Result 对象后添加 ? 操作符将同类的 Err 直接传递出去.
//? 符的实际作用是将 Result 类非异常的值直接取出,如果有异常就将异常 Result 返回出去。所以,?
//符仅用于返回值类型为 Result<T, E> 的函数,其中 E 类型必须和 ? 所处理的 Result 的 E 类型一致
fn call_myerro2(i: i32) -> Result<i32, bool> {
     let t = myerro(i)?;
     Ok(t)
}

//获取 Err 类型的函数是 kind().实现try catch
//Rust 似乎没有像 try 块一样可以令任何位置发生的同类异常都直接得到相同的解决的语法,但这样并不意味
//着 Rust 实现不了:我们完全可以把 try 块在独立的函数中实现,将所有的异常都传递出去解决

fn read_text_from_file(path: &str) -> Result<String, io::Error> {
     let mut f = File::open(path)?;
     let mut s = String::new();
     f.read_to_string(&mut s)?;
     Ok(s)
}

fn catch_ifreadfile_err() {
     let str_file = read_text_from_file("hello2.txt");
     match str_file {
          Ok(s) => println!("{}", s),
          Err(e) => match e.kind() {
               io::ErrorKind::NotFound => {
                    println!("No such file");
               }
               _ => {
                    println!("Cannot read the file");
               }
          },
     }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值