如果遇到错误,我编写了以下函数来读取文本文件的内容和$('#img1').html('<img src="getCommodityPic" />')
。
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,
}
在OO方法中,我还没有使用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!
是实现此功能的典型方法吗?如果没有,你能建议另一种方式吗?
答案 0 :(得分:1)
在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 The Rust Programming Language花费大量时间讨论try!
宏的原因:
Rust中错误处理的基石是
try!
宏。try!
宏抽象了像组合器一样的案例分析,但与组合器不同,它也抽象了控制流。也就是说,它可以抽象出上面提到的早期回归模式。
(这在页面的上下文中更有意义)
我不希望我的代码尝试从错误中恢复(很可能是由于找不到文件引起的) - 我希望它能够打印出有用的错误消息然后死掉
然后一定要恐慌。有更简洁,更详细的方法(如上图所示)。