赞
踩
两大类错误:
panic!宏执行时打印出一段错误提示信息,展开并清理当前的调用栈,然后退出程序。
panic中的栈展开与终止
panic发生时,程序会默认开始栈展开,反向遍历所有调用函数,并清理函数中的错误,需要二进制中存储许多额外信息。可以立即终止程序,而不进行任何清理,使用内存由操作系统回收。通过配置Carog.toml文件,减小二进制包。
[profile.release]
panic = ‘abort’
fn main() {
panic!("crash and burn");
}
fn main() {
let v = vec![1, 2, 3];
v[99]; //缓冲区溢出(buffer overread)
}
获得回溯信息,必须启用调试符号 (debug symbol),cargo build或cargo run不附带–release标志。
RUST_BACKTRACE=1 cargo run
enum Result<T, E> {
OK(T),
Err(E),
}
use std::fs::file;
fn main() {
let f = File::open("hello.txt");
//let f: u32 = File::open("hello.txt"); //报错查看类型
}
use std::fs::file;
fn main() {
let f = File::open("hello.txt");
let f = match f {
Ok(file) => file,
Err(error) => {
panic!("There was a problem opening the file: {:?}", error);
},
}
}
use std::fs::File; use std::io::ErrorKind; fn main() { let f = File::open("hello.txt"); let f = match f { Ok(file) => file, Err(error) => match error.kind() { ErrorKind::NotFound => match File::create("hell.txt") { OK(fc) => fc, Err(e) => panic!("Tried to create file but there was a problem: {:?}", e), }, other_error => panic!("There was a problem opening the file: {:?}", other_error), }, } }
use std::fs::File;
use std::io::ErrorKind;
fn main() {
let f = File::open("hello.txt").map_err(|error| {
if error.kind() == ErrorKind::NotFound {
File::create("hell.txt").unwrap_or_else(|error| {
panic!("Tried to create file but there was a problem: {:?}", error);
});
} else {
panic!("There was a problem opening the file: {:?}", other_error);
}
});
}
unwrap方法,Result返回值是Ok时,返回Ok内值;Error时,调用panic。
use std::fs::file;
fn main() {
let f = File::open("hello.txt").unwrap();
}
expect方法,在unwrap基础上指定panic!的错误提示信息。
use std::fs::file;
fn main() {
let f = File::open("hello.txt").expect("Failed to open hello.txt");
}
函数中包含可能会执行失败的调用时,可以将错误返回给调用者。
use std::io; use std::io::Read; use std::fs::File; 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 f.read_to_sttring(&mut s) { Ok(_) => Ok(s), Err(e) => Err(e), } }
?放于Result后,Result值是Ok时,返回Ok中的值并继续执行程序;Err时,返回并退出程序。
?运算符接收的错误值会隐式地被from函数处理,定义于标准库的From trait中,用于错误类型间转换(传入错误类型转换为当前函数返回错误类型)。
use std::io;
use std::io::Read;
use std::fs::File;
fn read_username_from_file() -> Result<String, io::Error> {
let mut f = File::open("hello.txt")?;
let mut s = String::new();
f.read_to_sttring(&mut s)?;
Ok(s)
}
use std::io;
use std::io::Read;
use std::fs::File;
fn read_username_from_file() -> Result<String, io::Error> {
let mut s = String::new();
File::open("hello.txt")?.read_to_sttring(&mut s)?;
Ok(s)
}
use std::io;
use std::fs;
fn read_username_from_file() -> Result<String, io::Error> {
fs.read_to_sttring("hello.txt")
}
use std::error::Error;
use std::fs::File;
fn main() -> Result<(), Box<dyn Error>> {
let f = File::open("hello.txt")?;
Ok(())
}
不可恢复用panic!,定义可能失败的函数(失败可预期)优先考虑使用Result。
示例、原型和测试使用panic!。
use std::net::IpAddr;
let home: IpAddr = "127.0.0.1".parse().unwrap();
loop { let guess: i32 = match guess.trim().parse() { Ok(num) => num, Err(_) => continue, }; if guess<1 || guess>100 { println!("The secret number will be between 1 and 100."); continue; } match guess.cmp(&secret_number) { } }
pub struct Guess {
value: i32,
}
impl Guess {
pub fn new(value: i32) -> Guess {
if value<1 || value>100 {
panic!("Guess number must be between 1 and 100, got {}.", value);
}
}
pub fn value(&self) -> i32 { //读取接口(getter)
self.value
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。