面试题答案
一键面试- 自定义错误类型:
在Rust中,可以使用
enum
来定义自定义错误类型,同时配合std::fmt::Display
和std::error::Error
trait来处理错误的展示和传播。use std::fmt; use std::io; #[derive(Debug)] enum FileReadError { FileNotFound, PermissionDenied, IoError(io::Error), } impl fmt::Display for FileReadError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { FileReadError::FileNotFound => write!(f, "File not found"), FileReadError::PermissionDenied => write!(f, "Permission denied"), FileReadError::IoError(e) => write!(f, "IO error: {}", e), } } } impl std::error::Error for FileReadError {}
- 在代码中使用
unwrap
方法: 假设使用std::fs::File::open
来打开文件,该函数返回一个Result
类型。我们可以通过map_err
将标准的io::Error
转换为我们自定义的FileReadError
,然后使用unwrap
。use std::fs::File; fn read_file() -> Result<String, FileReadError> { let file = File::open("example.txt") .map_err(|e| { if e.kind() == io::ErrorKind::NotFound { FileReadError::FileNotFound } else if e.kind() == io::ErrorKind::PermissionDenied { FileReadError::PermissionDenied } else { FileReadError::IoError(e) } })?; let mut contents = String::new(); file.read_to_string(&mut contents) .map_err(|e| FileReadError::IoError(e))?; Ok(contents) } fn main() { let result = read_file(); match result { Ok(contents) => println!("File contents: {}", contents), Err(e) => eprintln!("Error: {}", e), } // 如果确定在某些情况下不会发生错误,可以使用unwrap,但要谨慎 let safe_result = read_file().unwrap_or_else(|e| { eprintln!("Error: {}", e); String::new() }); println!("Safe result: {}", safe_result); }
- 保证
unwrap
使用的安全性:- 自定义错误类型转换:通过
map_err
将标准的io::Error
转换为自定义的FileReadError
,使得错误类型更具针对性。这样在使用unwrap
或者其他Result
处理方法时,我们能明确知道可能出现的错误类型。 - 错误处理前置:在
unwrap
之前,通过match
语句或者unwrap_or_else
方法对Result
进行处理。unwrap_or_else
允许我们在错误发生时执行特定的代码,如打印错误信息并返回一个默认值。这样即使在调用unwrap
时出现错误,程序也不会突然崩溃,而是以一种合理的方式继续执行(例如返回默认值),从而保证了unwrap
使用的安全性。同时,使用match
语句可以对不同类型的自定义错误进行分别处理,进一步增强程序的健壮性。
- 自定义错误类型转换:通过