Концепция ошибок
Часть раздела Основы путешествия по GO на Coddy — урок 102 из 109.
В Go ошибки — это значения, которые указывают на то, что что-то пошло не так. Go обрабатывает ошибки явно, а не с помощью исключений.
Давайте создадим функцию, которая может вызвать ошибку при делении чисел:
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}Эта функция возвращает два значения: результат деления и возможную ошибку. Если делитель равен нулю, мы возвращаем сообщение об ошибке вместо попытки выполнить деление.
Теперь давайте воспользуемся нашей функцией и обработаем любые потенциальные ошибки:
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}После выполнения этого кода мы увидим на экране сообщение об ошибке, потому что мы попытались разделить на ноль:
Error: cannot divide by zeroЭто демонстрирует паттерн обработки ошибок в Go: проверьте, произошла ли ошибка (err != nil), и затем предпримите соответствующие действия. Если ошибка не возникла, мы можем безопасно использовать результат.
Задание
ЛегкоВ этом испытании вы попрактикуетесь в работе с ошибками в Go. Вы создадите функцию, которая делит два числа и возвращает ошибку, если предпринимается попытка деления на ноль.
Ваша задача:
- Допишите функцию
divide, которая принимает два целых числа и возвращает их частное и ошибку. - Если делитель равен нулю, верните 0 и ошибку с сообщением "division by zero".
- Если деление допустимо, верните результат и
nilв качестве ошибки. - В функции
mainвызовитеdivideс предоставленными значениями и обработайте любые ошибки соответствующим образом.
Это упражнение демонстрирует, как функции в Go обычно возвращают результат и ошибку, а также как проверять и обрабатывать эти ошибки.
Шпаргалка
В Go ошибки — это значения, которые указывают на то, что что-то пошло не так. Go обрабатывает ошибки явно, а не с помощью исключений.
Функции, которые могут завершиться сбоем, возвращают два значения: результат и потенциальную ошибку:
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("cannot divide by zero")
}
return a / b, nil
}Чтобы обработать ошибки, проверьте, не является ли ошибка nil:
result, err := divide(10, 0)
if err != nil {
fmt.Println("Error:", err)
} else {
fmt.Println("Result:", result)
}Используйте errors.New() для создания новых сообщений об ошибках и возвращайте nil, когда ошибка не возникает.
Попробуйте сами
package main
import (
"errors"
"fmt"
)
// divide делит a на b и возвращает результат
// Если b равно 0, функция возвращает ошибку
func divide(a, b int) (int, error) {
// TODO: Реализовать функцию divide
// Если b равно 0, вернуть 0 и ошибку с сообщением "division by zero"
// В противном случае вернуть a/b и nil в качестве ошибки
}
func main() {
// Первый тестовый случай
a, b := 10, 2
result, err := divide(a, b)
if err != nil {
fmt.Printf("Error: %s\n", err)
} else {
fmt.Printf("Result: %d\n", result)
}
// Второй тестовый случай
a, b = 8, 0
result, err = divide(a, b)
if err != nil {
fmt.Printf("Error: %s\n", err)
} else {
fmt.Printf("Result: %d\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`Итоги — Принятие решений