Проверка ошибок есть везде. Иногда это сложнее, чем в другое время. Возьмем, к примеру, управление файлами. Вы должны помнить, что закрываете файл каждый раз, когда возвращаетесь… Если это не происходит автоматически.
Давайте посмотрим, как 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")
То есть… отлично. Поздравляю, Ява. Давайте посмотрим, как 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 также в значительной степени являются строками. Вы делаете пользовательскую ошибку с ошибками. Новый (“о нет”). Хороший материал, а теперь давайте взглянем на 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 удивительно работать. ошибки. Новое ("пользовательская ошибка")
удивительно. Java не так уж плоха, но Rust – “худший” для нас, ленивых людей, но и самый мощный. Плюс есть макросы, которые это исправляют.
Оригинал: “https://dev.to/legolord208/comparing-error-handling-in-java-go-and-rust”