我编写了以下函数,如果遇到错误,将读取文本文件和panic!
的内容。
fn get_file_contents(name: String) -> Result<String, io::Error> {
let mut f = try!(File::open(name));
let mut contents = String::new();
try!(f.read_to_string(&mut contents));
Ok(contents)
}
并使用以下方法从Result
中提取内容:
let file_contents = match get_file_contents(file_name) {
Ok(contents) => contents,
Err(err) => panic!("{}", err)
};
我现在正试图使用结构和实现以面向对象的方式重新实现这一点。我创建了以下结构:
struct FileReader {
file_name: String,
file_contents: String,
}
并实施了以下方法:
impl FileReader {
fn new(fname: &str) -> FileReader {
FileReader {
file_name: fname.to_string(),
file_contents: String::new(),
}
}
fn get_file_contents(&mut self) {
let mut f = match File::open(&self.file_name) {
Ok(file) => file,
Err(err) => panic!("{}", err)
};
match f.read_to_string(&mut self.file_contents) {
Ok(size) => size,
Err(err) => panic!("{}", err)
};
}
}
在OO方法中,我没有使用try!
宏,因为我不希望该方法返回任何值。我的get_file_contents
的OO实现是实现此功能的典型方法吗?如果没有,你能建议另一种方法吗?
发布于 2016-07-02 16:52:26
在OO方法中,我没有使用
try!
宏,因为我不希望该方法返回任何值。
不清楚为什么你认为“面向对象”意味着“不返回一个值”。如果可能发生错误,代码应该表明。
许多语言都有类似的异常--从函数或方法抛出的带外值(也称为“返回”)。请注意,这意味着这些语言允许从给定的函数返回两个不相交的类型:“普通”类型和“例外”类型。对于Rust的Result
:Result<NormalType, ExceptionalType>
,这是一个接近的等价物。
例外并不是一个很好的术语,因为您应该期望打开一个文件会失败。有无限多的方法不能工作,但只有一小部分的方式,它可以成功。
恐慌更接近于“立即杀死整个程序/线程”。与C不同的是,您必须处理问题,将其传回调用方,或终止程序(恐慌)。
如果在支持它们的语言中抛出异常,请使用Result
。如果您想要杀死程序,或者不想处理错误,请使用恐慌。
如果您想在特定情况下感到恐慌,请使用unwrap
,甚至更好的是使用expect
fn get_file_contents(&mut self) {
let mut f = File::open(&self.file_name).expect("Couldn't open file");
f.read_to_string(&mut self.file_contents).expect("Couldn't read file");
}
要处理每个方法的
Result
似乎有点笨重。
这就是为什么Error Handling section of 花费大量时间讨论try!
宏的原因:
Rust中错误处理的基石是
try!
宏。try!
宏像组合器一样抽象案例分析,但与组合器不同的是,它也抽象了控制流。也就是说,它可以抽象上面所示的早期返回模式。
(这在页面上下文中更有意义)
我不希望我的代码试图从错误中恢复(很可能是因为找不到文件)--我希望它打印一条有用的错误消息,然后死掉。
那一定要惊慌。有更简洁和更详细的方法来做它(如上面所示)。
https://stackoverflow.com/questions/38165707
复制