Урок 4. Ошибки без исключений

В «Сфере» нет исключений. Функция, которая может не получиться, возвращает обёртку результат из T с тремя полями: .успешно, .значение (только при успехе) и .сообщение (только при ошибке). Создают её функции успех(x) и ошибка("текст").

Свои функции с результатом

функция разделить(целое а, целое б): результат из целого
    если (б == 0)
        вернуть ошибка("деление на ноль");
    конец
    вернуть успех(а / б);
конец

функция главная(): целое
    результат из целого хорошо = разделить(10, 2);
    если (хорошо.успешно)
        вывести("10 / 2 = %(хорошо.значение)%");
    иначе
        вывести("Ошибка: %(хорошо.сообщение)%");
    конец

    результат из целого плохо = разделить(1, 0);
    если (плохо.успешно)
        вывести("1 / 0 = %(плохо.значение)%");
    иначе
        вывести("Ошибка: %(плохо.сообщение)%");
    конец
    вернуть 0;
конец
10 / 2 = 5
Ошибка: деление на ноль

Всегда проверяйте .успешно перед чтением .значение.

Встроенные функции

Многие встроенные функции — прочитать_файл, найти, подстрока, текст_в_целое — тоже возвращают результат:

функция главная(): целое
    результат из текста файл = прочитать_файл("несуществующий.txt");
    если ( не файл.успешно)
        вывести("Не удалось прочитать файл: %(файл.сообщение)%");
        вернуть 1;
    конец
    вывести(файл.значение);
    вернуть 0;
конец
Не удалось прочитать файл: не удалось открыть файл

Код возврата 1 из главной сообщает операционной системе, что программа завершилась с ошибкой.

Опциональный тип

Когда значения может просто не быть и сообщение не нужно, используйте тип? с полем .есть. Обычное значение «поднимается» в опциональное само, а отсутствие записывается словом неуказано:

функция главная(): целое
    целое? возраст = 25;
    целое? неизвестно = неуказано;

    если (возраст.есть)
        вывести("Возраст: %(возраст.значение)%");
    конец
    если ( не неизвестно.есть)
        вывести("Значение не задано");
    конец

    неизвестно = 30;
    если (неизвестно.есть)
        вывести("Теперь задано: %(неизвестно.значение)%");
    конец
    вернуть 0;
конец
Возраст: 25
Значение не задано
Теперь задано: 30

Ограничения: T — только числа и верно, а опциональные значения пока работают только как локальные переменные (не как параметры, не как поля).

Упражнения

  1. Напишите функцию корень_целый(n): результат из целого, которая возвращает ошибку для отрицательных чисел.
  2. Прочитайте число из файла и сложите его с единицей, обработав обе ошибки: нет файла и не число.

Дальше: Урок 5. Контракты и полиморфизм.