panic! 宏 —— 粗暴地抛出错误
在程序中抛出产生错误信息很容易,用 panic! 宏即可,程序运行到 panic! 会无条件结束,并返回错误信息。
fn main() {panic!("error!");println!("Hello, world!");
}================ run result ==============thread 'main' panicked at 'error!', src\main.rs:2:5
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Result 枚举类型 —— 优雅地返回错误
Result 枚举类型可以帮助我们优雅地返回函数错误,从而让调用者从容地处理错误。
fn foo(x: i32) -> Result<i32, String> {if x >= 0 {return Ok(x);} else {return Err("Error: Less than zero!".to_string());}
}fn main() {let a = foo(123);let b = foo(-123);println!("a={:?}", a);println!("b={:?}", b);
}================ run result ==============a=Ok(123)
b=Err("Error: Less than zero!")
在复杂一些,加入自己的错误处理代码:
fn foo(x: i32) -> Result<i32, String> {if x >= 0 {return Ok(x);} else {return Err("Error: Less than zero!".to_string());}
}fn bar(x: i32) -> Result<i32, String> {let t = foo(x);match t {Ok(i) => Ok(i),Err(s) => Err(s),}
}
fn main() {let a = bar(123);let b = bar(-123);println!("a={:?}", a);println!("b={:?}", b);
}================ run result ==============a=Ok(123)
b=Err("Error: Less than zero!")
更快捷的错误处理
Rust 提供的错误处理“短路”式处理模式,下面的函数 bar 代码与上面的等价,但是简化了很多:
fn bar(x: i32) -> Result<i32, String> {let t = foo(x)?;Ok(x)
}
foo(x)后面紧跟的 ? 号,表示如果出错则直接返回错误。当然,这必须在 foo、bar 两个函数错误返回类型完全一致时才有效。例如,函数 bar 可以写成如下形式,尽管返回的数据类型不一样,但错误信息类型一致就可以用短路模式处理错误信息。
fn bar(x: i32) -> Result<f64, String> {let t = foo(x)?;Ok(x as f64)
}
我觉得 Rust 的错误处理模式足以碾压目前所有的编程语言了。Rust 更进一步的错误处理技巧,我们将另写文章讨论。