Rust学习第五天——Panic

  • Rust的可靠性:错误处理——大部分情况下,在编译时提示错误并处理
  • 错误的分类:
  1. 可恢复
    1. 例如文件未找到,可再次尝试
  2. 不可恢复
    1. bug,例如访问索引超出范围
  • panic宏
fn main() {
    // panic!("crash and burn");

    let v = vec![1, 2, 3];

    v[99];
}
  • set RUST_BACKTRACE=full && cargo run:返回具体的回溯信息
  • 和Option枚举一样,Result及其变体也是有preclude代入作用域
use std::fs::File;

fn main() {
    // panic!("crash and burn");

    let f = File::open("hello.txt");

    let f = match f {
        Ok(file) => file,
        Err(error) => {
            panic!("Err opening file {:?}", error);
        },
    };
}
  • 匹配不同的错误(创建文档)
use std::{fs::File, io::ErrorKind};

fn main() {
    // panic!("crash and burn");

    let f = File::open("hello.txt");

    let f = match f {
        Ok(file) => file,
        Err(error) => match error.kind() {
            ErrorKind::NotFound => match File::create("hello.txt") {
                Ok(fc) => fc,
                Err(e) => panic!("Error create file: {:?}", e),
            },
            other_error => panic!("Error opening the file: {:?}", other_error),
        },
    };
}
  • match很有用,但是很原始(和上一段代码效果一样)
use std::{fs::File, io::ErrorKind};

fn main() {
    // panic!("crash and burn");

    File::open("hello.txt").unwrap_or_else(|error| {
        if error.kind() == ErrorKind::NotFound {
            File::create("hello.txt").unwrap_or_else(|error| {
                panic!("Error creating file: {:?}", error);
            })
        } else {
            panic!("Error opening file: {:?}", error);
        }
    });
}
  •  unwrap:match表达式的一个快捷方法;
  • expect:和unwrap类似,但可以指定错误信息

传播错误

use std::{fs::File, io, io::Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let f = File::open("hello.txt");

    let mut f = match f {
        Ok(file) => file,
        Err(e) => return Err(e),
    };

    let mut s = String::new();
    // 下面这个match是函数的返回值
    match f.read_to_string(&mut s) {
        Ok(_) => Ok(s),
        Err(e) => Err(e),
    }
}

fn main() {
    let result = read_username_from_file();
    println!("{:?}", result);
}
  • ?运算符:传播错误的一种快捷方式

(下面代码与上一段效果相同)

use std::{fs::File, io, io::Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let mut f = File::open("hello.txt")?;

    let mut s = String::new();
    // 下面这个match是函数的返回值
    f.read_to_string(&mut s)?;
    Ok(s)
}

fn main() {
    let result = read_username_from_file();
    println!("{:?}", result);
}
  • ?与from函数(被隐式处理)
  1. 当?调用from函数时:
    1. 它所接收的错误类型会转化为当前函数返回类型所定义的错误类型
  2. 用于针对不同错误原因,返回同一种错误类型
    1. 只要每个错误类型实现了转换为所返回的错误类型的from函数

还是一样的效果:

use std::{fs::File, io, io::Read};

fn read_username_from_file() -> Result<String, io::Error> {
    let mut s = String::new();
    File::open("hello.txt")?.read_to_string(&mut s)?;
    Ok(s)
}

fn main() {
    let result = read_username_from_file();
    println!("{:?}", result);
}
  • 开始优雅起来了,main函数也能修改返回值 

Box<dyn Error>是trait对象:任何可能的错误类型

use std::{fs::File, error::Error};

fn main() -> Result<(), Box<dyn Error>> {
    let f = File::open("hello.txt")?;
    Ok(())
}

 什么时候使用panic!

  • 总体原则:
  1. 在定义一个可能失败的函数时,优先考虑返回Result
  2. 否则就panic!

总结

        基础快学完了,内容也学一半了,感觉Rust真的是一门很好的语言,继续加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值