Результат или исключение
Допустим, у меня есть функция, которая должна возвращать
attached T
по телефону. Однако возвращает
detachable T
. Если
g
приводит к Void, я хочу вызвать такое исключение:
f: T
do
if attached g as res then
Result := res
else
raise
end
end
raise
do
(create {DEVELOPER_EXCEPTION}).raise
end
В этой настройке EiffelStudio выдает ошибку
VEVI: Variable is not properly set. Variable: Result
в конце .
Действительно, Результат может быть аннулирован в конце, но выполнение не должно доходить до конца
f
в этом случае должно было возникнуть исключение.
Как я могу реструктурировать код для достижения аналогичного результата?
3 ответа
Если тип возникшего исключения не имеет значения, подойдет следующий код:
f: T
do
Result := g
check is_g_attached: attached Result then end
end
Если важен тип возникшего исключения, функция
raise
можно дополнить постусловием
False
это означает, что функция больше не возвращается. Тогда код будет выглядеть так:
f: T
do
Result := g
if not attached Result then
raise
end
end
raise
do
(create {DEVELOPER_EXCEPTION}).raise
ensure
False
end
Только что узнал что
check
В этом случае можно использовать s:
f: T
do
if attached g as res then
Result := res
else
raise
end
check attached Result then end
end
Однако мне интересно, есть ли более чистый способ.
Я думаю, что вы можете уйти с:
f:T
do
check has_g: attached g then Result := g end
end
Код, естественно, сломается, если проверочное условиеattached g
не являетсяTrue
. Обратите внимание, что я довольно часто использую эту конструкцию, когда хочу убедиться, что такая функция, какg
прилагается.
Я также закодирую это как:
f:T
do
check has_g: attached g as al_result then Result := al_result end
end
Итак, вы можете спросить: чем это отличается и что означает префикс «al_»?
- В первом примере нет
as ____
беспорядок, что облегчает чтение и понимание (ИМХО). - Префикс «al_» — это соглашение об именах, которому я следую, где «al» означает «локальное вложение». Как читатель моего кода, я могу посмотреть на имя переменной и узнать, где эта переменная была объявлена.
Если у переменной нет префикса, то это ссылка на функцию самого класса.
Если префикс "l_?", то я смотрю на функцию
local
декларации.Если "al_", то я смотрю на
check
илиif .. then
или другой блок дляas
ключевое слово.Я также использую это для циклов, где
ic_?
является локальным объектом «Курсор итерации». Я использую это соглашение об именах и для символических циклов.