Error checking is everywhere. Sometimes it’s more complex than other time. Take file managing for example. You have to remember to close the file every time you return… If it’s not automatic.
Let’s see how Java does it. First, we’ll look at 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");
Enter fullscreen mode Exit fullscreen mode
Oh my God. OK, that is HORRIBLE. Let’s see how Java 7+ does.
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")
Enter fullscreen mode Exit fullscreen mode
That is… very good. Congrats, Java. Let’s see how Go does it.
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
Enter fullscreen mode Exit fullscreen mode
One thing to note with Go: Independent error handling. You can’t handle all errors clumped together. This is GOOD. This let’s you specify where exactly it went wrong. Errors in Go are also pretty much strings. You make a custom error with errors.New(“oh no”). Good stuff
Now let’s take a look at 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");
Enter fullscreen mode Exit fullscreen mode
After writing this, I had to look at the code again, thinking “that’s it”.
Like you can see, I clearly like Rust’s the most. Java 7’s is also good. Go’s is good, but defer statements only execute on function end, not scope based. You can of course close it manually, but that sucks too.
On the other hand, Go error types are amazing to work with. errors.New("custom error")
is amazing. Java’s is not too bad, but Rust’s is “worst” for us lazy people, but also the most powerful. Plus there are macros that fix this.
暂无评论内容