rust写编译器 8. 错误处理

不可恢复错误

fn add(a: u32,b: u32)->u32{
    // 没被调用不会报错
    unimplemented!()
}
fn derive_by_three(x: u32)->u32{
    for i in 0..{
        if 3*i<i{   
            panic("u32 overflow");
        }
        if x<3*i{
            return i-1;
        }
    }
    // 一定无法运行到这 
    // 不可到达宏,可以在程序无法走到但必须返回(return)东西的地方使用
    unreachable!() 
}
fn main() {
    // panic 宏
    // panic!("error!");
    // println!("aaa");   
    
    // 断言
    // assert!(1==2);
    // assert_eq!(1,2);
    
    // 未实现代码
    // let c = add(1,2); // 调用未定义代码会报错

    // 不应被访问代码
    
}

可恢复错误

fn main() {
    let a:Result<u32,&'static str>=Result::Ok(1);
    println!("{:?}", a);
    let a:Result<u32,&'static str>=Result::Err("result error");
    println!("{:?}", a);
    // 通常不会直接定义result,而是作为返回值使用
    let r = std::fs::read("/tmp/foo");
    match r {
        Ok(data) => println!("{:?}",std::str::from_utf8(&data).unwrap()),
        Err(err) => println!("{:?}",err),
    }
}

自定义错误与问号表达式

fn bar()->Result<u32,&'static str>{
    Ok(0)
}
fn foo()->Result<i32,&'static str>{
    // let a = bar()?;
    // Ok(a as i32)
    match bar() {
        Ok(a) => return Ok(a as i32),
        Err(e) => return Err(e),
    }
}
fn main() {
    println!("{:?}",foo());
}
#[derive(Debug)]
pub enum Error{
    IO(std::io::ErrorKind), 
}
impl From<std::io::Error> for Error{
    // 接收io::error转化为自定义Error
    fn from(error: std::io::Error)->Self{
        Error::IO(error.kind())
    }
}
fn do_read_file() -> Result<(),Error> {
    let data = std::fs::read("/tmp/foo1")?;
    let data_str = std::str::from_utf8(&data).unwrap();
    println!("{:?}", data_str);
    Ok(())
}
fn main() -> Result<(),Error> {
    // println!("{:?}",foo());
    // do_read_file().unwrap();
    do_read_file()?;
    println!("eee"); // 如果报错,走不到这
    do_read_file()?;
    do_read_file()?;
    Ok(())
}

 上一篇
rust写编译器 7. 作用域 rust写编译器 7. 作用域
所有权 fn main() { // eg.1 // 存在栈里 // let s1 = "hello world"; // 存在堆里 let s1 = String::from("hello worl
下一篇 
rust写编译器 9. 标准库 rust写编译器 9. 标准库
box智能指针 // 当有一个在编译时未知大小的类型,而又想要在需要确切大小的上下文中使用这个类型值 (递归) // ConsLint 每一项包含两个元素:当前项和下一项, // 结束项
  目录