Перейти к основному содержимому
Версия: 7.0

Выбор (CASE, IF, MULTI, OVERRIDE, EXCLUSIVE)

Оператор выбора создает свойство, которое для набора условий определяет, какое из этих условий выполняется, и возвращает значение соответствующего этому условию результата. Если выполняется сразу несколько условий, результатом будет результат, соответствующий первому из них в порядке перечисления. Если ни одно из условий не выполняется, то значением создаваемого свойства будет NULL.

Все условия и результаты задаются как некоторые свойства и/или параметры. Соответственно, условие выполняется, если значение свойства или параметра, с помощью которого задается это условие, не равно NULL.

Полиморфная форма​

Также в платформе существует возможность задавать условие и соответствующий ему результат одним свойством. В этом случае условием может являться либо принадлежность сигнатуре этого свойства, либо само это свойство. Такую форму оператора выбора будем называть полиморфной.

к сведению

Отметим то, что оператор экстремума и логические операторы также по сути являются разновидностями оператора выбора (причем его полиморфной формой, то есть условия и результат определяются одним свойством)

Взаимоисключаемость условий​

Для оператора выбора можно указать, что все его условия должны быть взаимоисключающими — для любого набора аргументов выполняется не более одного из них, поэтому результат уже не зависит от их порядка.

Неявное задание​

У этого оператора есть возможность неявного задания, при котором его условия и результаты добавляются по частям в разных модулях. Когда такой неявно заданный оператор дополнительно объявлен взаимоисключающим, его условия во всех модулях не должны пересекаться. Платформа проверяет это на этапе финализации модуля. Для оператора, заданного непосредственно, то же требование принимается на доверии.

Одиночная форма​

Оператор выбора в одиночной форме проверяет ровно одно условие. Если это условие выполняется, возвращается значение указанного результата. Также в этой форме существует возможность указать альтернативный результат, значение которого будет возвращаться, если условие не выполняется.

Опция взаимоисключения и неявное задание к одиночной форме не применимы.

Класс результата​

Результирующий класс — общий предок (встроенный или пользовательский) его возможных результатов. Если у возможных результатов нет общего предка (например, класс HTML и строковый класс), свойство не может принимать значений, и сервер при старте выдаёт ошибку property '...' is always NULL.

Язык​

Для создания свойства, реализующего общую форму выбора — явные условия с результатами — используется оператор CASE.

В полиморфной форме MULTI выбирает операнд, сигнатура которого соответствует классам параметров; OVERRIDE возвращает первый операнд, значение которого не равно NULL; EXCLUSIVE делает то же самое, что и OVERRIDE, и дополнительно декларирует, что одновременно не равно NULL значение не более чем одного операнда.

В одиночной форме оператор IF возвращает результат, когда условие выполняется, а оператор IF ... THEN дополнительно принимает альтернативный результат, возвращаемый, когда условие не выполняется.

Примеры​

CLASS Color;
id = DATA STRING[100] (Color);

background 'Цвет' (Color c) = CASE
WHEN id(c) = 'Black' THEN RGB(0,0,0)
WHEN id(c) = 'Red' THEN RGB(255,0,0)
WHEN id(c) = 'Green' THEN RGB(0,255,0)
;

id (TypeExecEnv type) = CASE EXCLUSIVE
WHEN type = TypeExecEnv.materialize THEN 3
WHEN type = TypeExecEnv.disablenestloop THEN 2
WHEN type = TypeExecEnv.none THEN 1
ELSE 0
;
nameMulti (Human h) = MULTI 'Male' IF h IS Male, 'Female' IF h IS Female;

CLASS Ledger;
CLASS InLedger : Ledger;
quantity = DATA INTEGER (InLedger);

CLASS OutLedger : Ledger;
quantity = DATA INTEGER (OutLedger);

signedQuantity (Ledger l) = MULTI quantity[InLedger](l), quantity[OutLedger](l);
CLASS Group;
markup = DATA NUMERIC[8,2] (Group);

markup = DATA NUMERIC[8,2] (Book);
group = DATA Group (Book);
overMarkup (Book b) = OVERRIDE markup(b), markup(group(b));

notNullDate (INTEGER i) = OVERRIDE date(i), 2010_01_01;
background 'Цвет' (INTEGER i) = EXCLUSIVE RGB(255,238,165) IF i <= 5,
RGB(255,160,160) IF i > 5;

CLASS Human;

CLASS Male : Human;
CLASS Female : Human;

name(Human h) = EXCLUSIVE 'Male' IF h IS Male, 'Female' IF h IS Female;
name = DATA STRING[100] (Book);
hasName (Book b) = TRUE IF name(b);

background (Book b) = RGB(224, 255, 128) IF b IS Book;

countTags (Book b) = GROUP SUM 1 IF in(b, Tag t);
price1 = DATA NUMERIC[10,2] (Book);
price2 = DATA NUMERIC[10,2] (Book);
maxPrice (Book b) = IF price1(b) > price2(b) THEN price1(b) ELSE price2(b);

// если h будет другого класса, то будет NULL
sex (Human h) = IF h IS Male THEN 'Male' ELSE ('Female' IF h IS Female);

isDifferent(a, b) = IF a != b THEN TRUE;