- •4.9.1. Изменяемость
- •4.9.2. Классы операций
- •98 Глава 4
- •4.9.3. Полнота
- •100 Глава 4
- •4.9.5. Операции egual, similar и copy
- •102 Глава 4
- •104 Глава 4
- •5. Исключительные ситуации
- •108 Глава 5
- •110 Глава 5
- •6.2.1. Сигнализация об исключительных ситуациях
- •5.2.2. Обработка исключительных ситуаций
- •112 Глава 5
- •5.2.3. Предложение resignal
- •6.2.4. Необрабатываемые исключительные ситуации
- •114 Глава 5
- •6.2.3. Предложение resignal
- •5.2.4. Необрабатываемые исключительные ситуации
- •116 Глава 5
- •118 Глава 5
- •118 Глава 5
- •120 Глава 5
- •122 Глава 5
- •124 Глава 5
- •128 Глава 6
- •130 Глава 6
- •6.2.1. Реализация итераторов
- •6.2.2. Использование итераторов
- •132 Глава 6
- •134 Глава 6
- •136 Глава 6
- •138 Глава 6
- •140 Глава 7
- •142 Глава 7
- •7.2. Абстракция данных
- •144 Глава 7
- •146 Глава 7
- •148 Глава 7
- •150 Глава 7
- •7.4. Генераторы
- •162 Глава 7
- •154 Глава 7
- •156 Глава 7
- •162 Глава 8
- •164 Глава 8
- •166 Глава 8
- •168 Глава 8
- •170 Глава 9
- •172 Глава 9
- •174 Глава 9
- •176 Глава 9
- •9.1.3. Пример
- •178 Глава 9
- •180 Глава 9
- •182 Глава 9
- •184 Глава 9
- •186 Глава 9
- •188 Глава 9
- •190 Глава 9
- •192 Глава. 9
- •194 Глава 9
120 Глава 5
create = proc ( ) returns (cvt) return (rep$make_empty (nil)) end create
addel = proc (s: cvt, v; t) signals (dupl) tagcase s fag some (n: node): it v < n.val then signal dupl elseif v < n.val then addel (n.left, v) else addel (n.right, v) end resignal dupl tag empty:
rep$change_some (s, tiode${val: v, left: create (), right: create ())) end end addel
rernel = proc (s: cvt, v: t) signals (notJn) tagcase s tag empty: signal notJn tag some (n: node): if v == n.val then if empty (n.right) then % заменить узел на лево? поддерево rep$v_get_v (s, down (n. left))
else % сделать n.val значением из правого поддерева n.val :== least (n.right) remel (n.right, n.val) end
elseif v < n.val then remel (n.left, v) else remel (n.right, v) end resignal not_in end end remel
isJn = proc (s: cvt, v: t) returns (bool) tagcase s tag empty: return (false) tag some (n: node): if v = n.val then return (true) elseif v < n.val then return (isJn (n.left, v)) else return (isJn (n.right, v)) end end end isJn
least = proc (s: cvt) returns (t) signals (empty) tagcase s tag empty: signal empty tag some (n: node): return (least (n.left)) end except when empty: return (n.val) end end least
empty = proc (s: cvt) retunis (bool) return (rep$is_empty (s)) end empty
end olist Рис. 5.6, Реализация упорядоченных списков.
Исключительные ситуации
summation^ proc [t: type] (x: iist [t], zero; t) returns (t)
signals (underflow, overflow) requires t имеет операцию добавления:
add: proctype(t, t) returns (t) signals (underflow, overflow) effects Создает сумму элементов в x, начиная с zero; сигнализирует об искл. ситуациях underflow или overflow в случае возникновения потери значимости или переполнения при вычислении суммы.
summation = proc [t: type] (x: list (t], zero: t) returns (t)
signals (underflow, overflow) where t has add: proctype (t, t) returns (t)
signals (underflow, overflow) sum: t : == zero while true do sum ;= sum-{- list [t]$first (x) % используется t$add
except when empty: return (sum) end x := list [t]$rest (x) end resignal underflow, overflow end summation
Рис. 5.7. Процедура summation.
5.4. Некоторые аспекты проектирования программ
Исключительные ситуации следует использовать для устранения большинства ограничений, перечисленных в предложениях requires. Эти предложения следует оставлять только из соображений эффективности или если контекст использования настолько ограничен, что мы можем быть уверены, что ограничения удовлетворяются. Например, процедура search будет, вероятно, требовать, чтобы массив был упорядочен, так как в этом случае она может быть реализована намного более эффективно. Точно так же процедура merge, используемая для сортировки слиянием (рис. 3.2), будет требовать, чтобы ее аргументы были упорядочены, так как, с одной стороны, это улучшает эффективность и, с другой стороны, потому что контекст ее использования ограничен.
Исключительные ситуации также следует использовать для того, чтобы избежать кодирования информации в обычных результатах. Например, процедура getind кластера набора целых чисел (рис. 5.4) сигнализирует об исключительной ситуации, если элемент не находится в массиве, а не возвращает элемент, больший, чем верхняя граница. Лучше передавать эту информацию с помощью исключительной ситуации, так как возвращаемый в этом случае результат не может быть использован как обычный результат. Используя исключительную ситуацию, мы можем легко отличать этот результат от обычного, что позволяет избежать потенциальной ошибки.
Когда процедура имеет смысл только для аргументов, принадлежащих подмножеству ее области определения, в реализации этой процедуры допускается делать с не принадлежащими этому подмножеству аргументами все, что угодно. Конечно, не все
