- •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
132 Глава 6
бстракция итерации
setsum, когда к ней обращаются с набором intset jl, 4, 71, предполагая, что представляющий этот набор массив содержит эти элементы в порядке 4, 1, 7, На этом рисунке показаны значения локальных в процедуре setsum переменных sum и е и локальной в операции elements переменной i сразу же после выдачи элемента. Показано также значение переменной sum после окончания цикла в процедуре setsum. В этом случае значения переменных i и е не показаны, поскольку обращение к операции elements и тело цикла завершилось. После выдачи каждого элемента счетчик команд (рс) в процедуре setsum находится в начале тела оператора for, а счетчик команд для операции elements находится на операторе, следующем за оператором yield, г. е. на операторе присваивания для переменной i.
На рис. 6.6 показан второй пример использования операции elements — поиск некоторого отрицательного элемента. Если выданный элемент отрицателен, то процедура find. neg сразу же выдает результат. При этом возврате оператор for, а значит, и операция elements завершают работу до того, как будут выданы другие целые числа в наборе intset.
find.neg= pi-ос (s: intset) returns (int) signal (notJouiid) for x: int in intsel$e!ernents (s) do if x < 0 then return (x) end er.d signal not „found end find.neg
Рис. 6.6. Использование итератора для поиска.
К итераторам можно обращаться только из операторов for, и из каждого оператора for можно обращаться только к одному итератору. Однако операторы for могут быть вложенными. Кроме того, итераторы могут быть реализованы при помощи операторов for и их реализация может быть рекурсивной. Некоторые такие примеры приводятся в разд. 6.3.
6.2.3. Встроенные итераторы
В языке CLU имеется ряд операций итераторов для встроенных типов. Для целых чисел имеется операция intSfrom.to,
from. to == iter(x, у: int) yields (int)
effects Выдает целые числа между x и у включительно в порядке следования.
Имеется также операция int$from_to.by, чей третий аргумент задает величину, на которую увеличивается переменная х на каждой итерации. Для массивов (и последовательностей) имеется два итератора — операция elements, которая выдает элементы массива (или последовательности) от нижней границы до верхней
границы, и операция indexes, которая выдает индексы массива (или последовательности) от нижней границы до верхней границы. И наконец, строки имеют итератор chars, который выдает символы строки от первого до последнего.
Примеры
В этом разделе приводится несколько примеров итераторов. Первый пример, приведенный на рис. 6.7, — это простой «фильтр». Он называется фильтром потому, что удаляет некоторые элементы, выданные другим итератором, и выдает только остальные элементы в процедуру, которая к нему обращается.
filter = iter (s: intset, els: itertype (intset) yields (int),
pred: proctype (int) returns (bool)) yields (int) requires чтобы s не модифицировался в теле цикла. effects Выдает в произвольном порядке все элементы, выданные операцией els (s), которые удовлетворяют условию, заданному в pred',
iter (s: intset, els: itertype (intset) yields (int),
pred: proctype (int) returns (bool)) yields (iiit) for е: int in els (s) do if pred (e) then yield (е) end end end filter
Рис. 6.7. Фильтр.
Например, если операция odd выдает значение true, только если ее целый аргумент является нечетным числом, то фильтр
filter (s, intset^elements, odd)
выдает нечетные числа из набора s. В качестве второго примера добавим операцию
smalLto.big к упорядоченному списку olist.
small_to.big= iter (s, olist [t]) yields (t) requires чтобы набор s не модифицировался в теле цикла. effects Выдает элементы набора s в возрастающем порядке, определяемом при помощи операции t$lt, причем каждый элемент только один раз.
Эта операция могла бы заменить операцию least, описанную ранее. Реализация показана на рис. 6.8. Она рекурсивна — сперва операция small, to_big обращается рекурсивно сама к себе для любого поддерева, затем она выдает значение в узле, и далее она обращается рекурсивно сама к себе для правого поддерева. Заметим, между прочим, что операция smalLto_big является некоторой абстракцией через параметризацию. Она наследует тип параметра t из упорядоченного списка olist.
