Результат или исключение

Допустим, у меня есть функция, которая должна возвращать 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_»?

  1. В первом примере нетas ____беспорядок, что облегчает чтение и понимание (ИМХО).
  2. Префикс «al_» — это соглашение об именах, которому я следую, где «al» означает «локальное вложение». Как читатель моего кода, я могу посмотреть на имя переменной и узнать, где эта переменная была объявлена.
  • Если у переменной нет префикса, то это ссылка на функцию самого класса.

  • Если префикс "l_?", то я смотрю на функциюlocalдекларации.

  • Если "al_", то я смотрю наcheckилиif .. thenили другой блок дляasключевое слово.

  • Я также использую это для циклов, гдеic_?является локальным объектом «Курсор итерации». Я использую это соглашение об именах и для символических циклов.

Другие вопросы по тегам