Перейти к основному содержимому

Практика: Обработка ошибок и паники


Онлайн редактор кода для Go

Здесь вы можете попробовать свои силы в программировании на языке Go. Для этого мы предоставляем вам онлайн редактор кода, в котором вы можете написать свой код и запустить его.

❗️ При обновлении страницы код пропадёт, по этому, сохраните свой код куда-нибудь, если он важный.

Задание 1: Безопасный делитель

Задание 1: Безопасное деление

Напиши функцию SafeDivide(a, b float64) (float64, error). Если b == 0 — верни ошибку через fmt.Errorf. В main протестируй несколько пар чисел (включая деление на ноль) и обработай ошибку красиво.


💡 Подсказка

Проверяй b == 0 в самом начале функции.

Сообщение об ошибке делай информативным — включай значение a.

В main используй if err != nil для красивого вывода ошибки.

Для успешного случая выводи результат с двумя знаками после запятой.

Задание 2: Проверка возраста

Задание 2: Валидация возраста

Напиши функцию CheckAge(age int) error. Возвращай ошибку, если возраст < 0 или > 150. В main проверь несколько значений и обработай ошибки по-разному.


💡 Подсказка

Используй две отдельные проверки: возраст < 0 и возраст > 150.

Сообщения об ошибках делай разными и информативными.

В main выводи разные сообщения в зависимости от типа ошибки (можно через строки или просто отдельно).

Проверь граничные значения (0, 150, 151).

Задание 3: Парсер положительных чисел

Задание 3: Парсер положительных чисел

Напиши функцию ParsePositiveInt(s string) (int, error). Используй strconv.Atoi. Обрабатывай ошибки преобразования и проверяй, что число > 0. В main протестируй разные строки.


💡 Подсказка

Сначала используй strconv.Atoi(s) — он сам обрезает пробелы.

Если ошибка преобразования — оберни её через fmt.Errorf.

Если число <= 0 — своя ошибка.

В main выводи разные сообщения в зависимости от типа ошибки.

Задание 4: Валидатор супергероя

Задание 4: Валидация супергероя

Создай структуру Superhero с полями Name и PowerLevel. Добавь метод Validate() error с проверками: имя не пустое, сила от 1 до 1000. В main создай несколько героев и проверь валидацию.


💡 Подсказка

Метод Validate() с pointer receiver (*Superhero), если хочешь изменять поля (но здесь не нужно).

Проверяй пустое имя (len(strings.TrimSpace(s.Name)) == 0) и границы PowerLevel.

Возвращай разные ошибки для разных случаев.

В main выводи понятные сообщения об успехе или ошибке.

Задание 5: Atoi (Строка в число)

Задание 5: String to Integer (atoi) — (L8)

Реализуй функцию myAtoi(s string) int, которая преобразует строку в 32-битное целое число (int32). Учитывай пробелы, знак, переполнение и некорректные символы по правилам задачи.


💡 Подсказка
  • Пропускай начальные пробелы — это "нормальное" поведение.
  • Определи знак — если есть '+' или '-', запомни его.
  • Собирай цифры, но на каждом шаге проверяй, не выходит ли результат за границы int32.
  • Если переполнение — возвращай math.MaxInt32 или math.MinInt32 в зависимости от знака.
  • Если встретил не цифру — остановись (это "ошибка" в строке).

Не используй strconv.Atoi — реализуй вручную, чтобы понять, как Go обрабатывает такие граничные случаи.

Проверь на дополнительных примерах — особенно на переполнении и некорректных строках.

Задание 6: Паника и восстановление

Задание 6: Аварийная остановка ракеты

Напиши функцию LaunchRocket(fuel int). Если топлива < 100 — паника. В main используй defer + recover для перехвата паники и вывода спокойного сообщения.


💡 Подсказка

В LaunchRocket используй panic() при недостатке топлива.

В main оберни вызов в функцию с defer func() { if r := recover(); r != nil { ... } }.

В recover выводи сообщение о пойманной панике и что всё под контролем.

Проверь разные значения топлива.

Задание 7: Pow(x, n)

Задание 7: Pow(x, n) — возведение в степень (L50)

Реализуй функцию myPow(x float64, n int) float64 — возведение x в степень n. Учитывай переполнение, отрицательные степени и n = 0.


💡 Подсказка

Здесь ошибки — это переполнение и особые случаи:

  • n == 0 → всегда 1.0
  • n < 0 → вычисляй 1 / myPow(x, -n), но будь осторожен с x == 0
  • Если |x| < 1 и |n| очень большой — результат → 0 (переполнение вниз)
  • Если |x| > 1 и |n| большой — результат → +Inf или -Inf

Используй быстрый алгоритм (binary exponentiation) — он эффективен и помогает избежать промежуточного переполнения.

Проверяй на дополнительных примерах — особенно на граничных значениях n и x близких к 0 или 1.

Задание 8: Кастомная ошибка миссии

Задание 8: Кастомная ошибка для миссии

Создай свой тип ошибки MissionError с полями Code и Message. Реализуй метод Error(). Напиши функцию CheckMission(code int) error. В main используй type assertion для красивого вывода.


💡 Подсказка

Структура MissionError с полями Code и Message.

Метод Error() возвращает строку с кодом и сообщением.

В CheckMission возвращай &MissionError{...} при ошибке.

В main используй type assertion: if missionErr, ok := err.(*MissionError); ok { ... }

Дополнительные материалы

  • Поиграйся с errors.Is и errors.As
  • Добавь логирование ошибок через slog
  • Придумай свои кастомные ошибки для валидации
Совет

Ошибки в Go — это не страшно. Это просто значения. Обрабатывай их явно — и твой код станет надёжным и предсказуемым!

Следующий урок

Конкурентность: горутины и каналы.