Цитата:
Для функций, возвращающих значение, он, действительно, неудобен - выражения будут очень громоздкими и нечитабельными.
Если функция не в состоянии гарантированно вернуть результат, то результат нужно возвращать через дополнительный параметр, а возвращаемое значение - флаг ошибки. Иначе у нас только два выхода:
1) Перегрузка результата. Самый худший из способов. Считать что <0, -1, -2, 2^32-1, 0, '' или как в динамических языках false/null - это ошибка, а остальные значения - ок. В чём проблема? Во-первых, мешается информация с метаинформацией (значение и флаг ошибки в одном параметре). Во-вторых, проверять всё равно нужно. А если не проверять, ради "удобства" и "читаемости", то в отличие от FlagError с незамедлительным остановом мы получаем ошибочное поведение. Наконец, обилие типов подобной метаинформации обычно зашкаливает и провоцирует на ошибки.
2) Бросание исключения любой функцией, чей результат не гарантирован.
Если применять исключения в виде catch, неясно, что будет в следующей ситуации:
C:=sin(a) + sin(b);
catch ... // А что ловим? Проблема в "a" или в "b"?
Это раз. Во-вторых, теряется возможность на основе логического результата писать цепочки функций:
IF NOT (OpenFile(...) AND ReadWholeFile(...) AND (FileSize > 0)) THEN
...
ELSE
...
END;
Логические выражения с функциями, основанными на булевом результате записываются и комбинируются легко при помощи OR, AND, NOT. В случае исключений всё гораздо хуже. Нужно ставить обработчики часто и усложнять код для поддержки выходов из середины функций.
Исключения в таком виде эмулируют следующую конструкцию: Res:=A AND B AND C;
Иными словами, в блок обработки исключений попадаем, если хотя бы одна функция из цепочки сгенерировала исключение. А вот более сложные условия - увы.
Предположим, что две функции с негарантированным результатом используют исключения для сигналов ошибки. Как написать следующее выражение: Found:=FindOnLocalPC(...) OR FindOnServer(...) в стиле обработки исключений?
Код:
Found:=FALSE;
TRY
Res:=FindOnLocalPC;
Found:=TRUE;
EXCEPT
END;
IF NOT Found THEN
TRY
Res:=FindOnServer;
Found:=TRUE;
EXCEPT
END;
END;