Основы обработки ошибок
Часть раздела Основы путешествия по GO на Coddy — урок 108 из 109.
Базовая обработка ошибок — это фундаментальный паттерн в Go, при котором вы проверяете наличие ошибок после операций, которые могут завершиться неудачей.
Давайте узнаем, как обрабатывать ошибки в Go, создав простую функцию деления, которая возвращает ошибку при делении на ноль:
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}Эта функция возвращает два значения: результат деления и ошибку. Если делитель равен нулю, она возвращает сообщение об ошибке вместо попытки выполнить деление.
Теперь давайте посмотрим, как использовать эту функцию и обрабатывать возможные ошибки:
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error occurred:", err)
return // Остановить выполнение или обработать ошибку
}
fmt.Println("Result:", result)После выполнения этого кода мы проверяем, произошла ли ошибка, используя условие if err != nil. Так как мы попытались разделить на ноль, функция возвращает ошибку, и на экране отобразится следующее:
Error occurred: division by zeroЭтот паттерн возврата ошибки в качестве последнего возвращаемого значения и её немедленной проверки очень распространен в Go. Это позволяет вашей программе корректно обрабатывать сбои вместо аварийного завершения.
Задание
ЛегкоВ этом испытании вы попрактикуетесь в базовой обработке ошибок в Go. У вас есть функция, которая делит два числа, но деление на ноль вызывает ошибку времени выполнения. Ваша задача — добавить обработку ошибок, чтобы предотвратить этот сбой.
В коде уже есть функция, которая возвращает и результат, и ошибку. Вам нужно проверить наличие ошибки перед использованием результата.
Шпаргалка
В Go функции, которые могут завершиться с ошибкой, возвращают ошибку в качестве последнего возвращаемого значения:
func divide(a, b int) (int, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}Проверяйте наличие ошибок с помощью if err != nil:
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error occurred:", err)
return // Остановить выполнение или обработать ошибку
}
fmt.Println("Result:", result)Этот паттерн позволяет программам корректно обрабатывать сбои вместо аварийного завершения.
Попробуйте сами
package main
import (
"errors"
"fmt"
)
// Эта функция делит x на y и возвращает ошибку, если y равен нулю
func divide(x, y float64) (float64, error) {
if y == 0 {
return 0, errors.New("cannot divide by zero")
}
return x / y, nil
}
func main() {
// Тестовые значения
numerator := 10.0
denominator := 0.0
// Вызов функции divide
result, err := divide(numerator, denominator)
// TODO: Проверить, не является ли err отличным от nil (есть ли ошибка)
// Если есть ошибка, вывести её с помощью fmt.Println(err)
// В противном случае вывести результат с помощью fmt.Printf("Result: %.2f\n", result)
// Удалите эту строку и реализуйте правильную обработку ошибок выше
fmt.Printf("Result: %.2f\n", result)
}В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Основы
4Операторы сравнения и логические операторы
Операторы сравнения — Часть 1Операторы сравнения — Часть 2Логический оператор ANDЛогический оператор ORЛогический оператор NOTОсновы приоритета операторовИтоги: выполнение сравнений7Управляющие конструкции: Циклы
Что такое цикл `for`Цикл `for` — основыЦикл `for` — только условиеКлючевое слово `break`Ключевое слово `continue`Вложенные циклыИтоги — повторение действий2Переменные и базовые типы данных
Что такое переменнаяВывод типов с помощью `:=`Целые числа (int)Числа с плавающей точкойЛогический тип (Booleans)СтрокиНулевые значения (Zero Values)КонстантыПравила именованияИтоги: переменные и типы5Основы ввода-вывода
Форматированный выводСпецификаторы форматаВывод типовБазовый ввод данных пользователемИтоги: ввод и вывод8Функции
Понимание функцийОбъявление функцииВызов функцийПараметры функцииВозврат одного значенияВозврат нескольких значенийИменованные возвращаемые значенияОсновы области видимости функцийИтоги — создание переиспользуемого кода11Составные типы: Срезы
Введение в срезыОбъявление литералов срезовСоздание срезов с помощью `make`Длина и емкость срезаДоступ к элементам срезаДобавление элементовПолучение срезов из существующих срезов/массивовИтерация по срезамКопирование срезовИтоги: Динамические списки14Основы обработки ошибок
Концепция ошибокИнтерфейс `error`Функции, возвращающие ошибкиПроверка ошибокСоздание простых ошибокСоздание форматированных ошибокОсновы обработки ошибокИтоги — решение проблем3Базовые операторы
Арифметические операторыОператор деленияОператор остатка от деленияОператор присваиванияКомбинированные операторы присваиванияИнкремент и декрементПовторение — Вычисления6Управление потоком: Условные конструкции
Оператор `if`Ключевое слово `else`Ключевое слово `else if`Затенение переменных в `if`Инициализация переменныхОператор `switch`Switch с выражениямиSwitch без выраженийКлючевое слово `fallthrough`Итоги — Принятие решений