错误检查无处不在。 有时,它比其他时候更复杂。 以文件管理为例。 您必须记得每次返回时都要关闭文件...如果不是自动的。
让我们看看Java是如何做到的。 首先,我们来看一下Java 6-。
BufferedReader reader;
try {
reader = new BufferedReader(new FileInputStream("test.txt"));
// read file
if (condition) {
// closed by finally block
return;
}
// closed by finally block
} catch(Exception e) {
// do proper error handling
// closed by finally block
} finally {
try {
reader.close();
} catch(Exception e) {
// do proper error handling
}
}
System.out.println("File read");
哦,我的上帝。 好,那太可怕了。 让我们看看Java 7+是如何工作的。
try(BufferedReader reader = new BufferedReader(new FileInputStream("test.txt"))) {
// read file
if (condition) {
// automatically closed
return;
}
// automatically closed
} catch(Exception e) {
// do proper error handling
// automatically closed
}
System.out.println("File read")
这是非常好的。 恭喜,Java。 让我们看看Go是如何做到的。
file, err := os.Open("test.txt") // no semicolon :(
// i love semicolons :(
if err != nil {
// do proper error handling
}
defer file.Close()
// read file
if condition {
// closed by defer
return
}
fmt.Println("File read")
// File closed on return, so you probably wanna return ASAP
Go需要注意的一件事:独立错误处理。 您无法处理聚集在一起的所有错误。 很好 这让您指定错误的确切位置。 Go中的错误也是很多字符串。 您使用error.New(“ oh no”)进行了自定义错误。 好东西 现在让我们看一下Rust。
{ // Start a new scope. You don't *have* to do this
let file = match File::open("test.txt") {
Ok(file) => file,
Err(err) => {
// do proper error handling
return;
}
};
// read file
if condition {
// out of scope - automatically closed
return;
}
// out of scope - automatically closed
}
println!("File read");
编写完此代码后,我不得不再次查看代码,以为“就是这样”。 如您所见,我显然最喜欢Rust。 Java 7也不错。 Go是好的,但是defer语句仅在函数端执行,而不是基于作用域。 您当然可以手动将其关闭,但这也很麻烦。 另一方面,Go错误类型非常适合使用。errors.New(“自定义错误”)是惊人的。 Java并不是很糟糕,但是Rust对于我们懒惰的人来说“最糟糕”,但也是最强大的。 另外,还有一些宏可以解决此问题。