В статье рассматриваются следующие вопросы:
- тип данных вариант;
- передача значений типа вариант в процедуру;
- оператор выбора case;
- пример программы.
Delphi 7. Занятие 2_6. Часть 3.
В delphi варианты являются своеобразной альтернативой концепции контроля типов переменных компилятором.
Компилятор строго следит за совместимостью типов переменных, присутствующих в операторе (выражении).
Это исключает попытки, например, прибавить строковое значение к числовому или приравнять целочисленную левую часть выражения к действительному значению.
Единственное неявное преобразование возможно только в выражении:
переменная_вещественного_типа:=выражение, содержащее переменные_вещественного_типа и переменные_целого_типа (а также константы этих типов);
Но выражение:
переменная_целого_типа:=выражение, содержащее переменные_вещественного_типа и переменные_целого_типа (а также константы этих типов);
компилятор не пропустит.
Выражение справа должно содержать только константы и переменные целого типа!
Кроме того, переменная указанного типа не может принимать значения другого типа (исключение — вышеуказанная ситуация). Например, если переменная описана как имеющая тип string, то в неё нельзя записать значение типа double.
Однако в delphi всё же существует исключение, которое оказывается весьма полезным в некоторых ситуациях.
Это переменные типа variant.
В переменную этого типа можно последовательно записывать значения практически любого простого типа, а также ссылки на OLE объекты.
Покажем это на примере.
Однако предварительно рассмотрим новый оператор.
Case delphi — оператор выбора.
В delphi оператор выбора case позволяет переключаться между альтернативами. Его синтаксис:
case переменная_выбора of
метка_выбора_1:begin выполняются операторы end; //выход из case
метка_выбора_2, метка_выбора_3:begin … end;//выход из case
…
метка_выбора_n:begin … end //точка с запятой не ставится!//выход из case
else
begin … end //точка с запятой не ставится!//выход из case
end; //завершение оператора case
Например:
case vL of
1:begin … end;
2,4:begin … end
else
begin … end
end;
Если значение переменной vL будет равно 1, то выполняется ветка, метка которой равна 1 (будут выполнены операторы, стоящие после двоеточия). После этого происходит выход из оператора case.
Если vL будет равно 2 или 4 — то выполнится ветка 2,4:begin … end.
Если vL не будет равно ни 1, ни 2, ни 4 — то выполнится ветка else begin … end.
Ветка else может отсутствовать. Тогда, если vL не равна 1, 2 или 4 — то просто происходит выход из оператора выбора case.
Переменная vL может быть любого порядкового типа: целая, логическая, символьная, перечисляемая, тип-диапазон (о последних двух типах разговор в дальнейшем).
Например:
case i of //переменная i целого типа
1:begin … end;
2,5:begin … end;
end; //case
case c of //переменная c символьного типа
‘a’:begin … end;
‘b’,’d’:begin … end;
else begin … end
end; //case
case b of //переменная b логического типа
false:begin … end;
true:begin … end;
end; //case
Передача в процедуру варианта
Параметр-значение типа variant.
Создадим процедуру, в которую будем передавать параметр-значение типа «вариант» и параметр-переменную типа «строка».
procedure prV(vv:variant; var str:string);
var s,sw:string; i:integer;
begin
i:= varType(vv); //функция varType() определяет и возвращает код типа данных, передаваемых вариантной переменной. Возвращается значение целого типа.
s:=intToStr(i);
case i of //новый оператор — оператор выбора; пояснения ниже;
6,11,17,18,256:begin //6,11,17,18,256 – коды типов вариантной переменной vv
//6 — вещественный тип; 11- логический тип; 17 — тип целое;
//18 — тип word (слово); 256 — строка или дата/время;
sw:=vv; //только вариантная переменная допускает такое присваивание! Любой простой тип превращается в строку.
str:=str+sw+’ №’+s; //формируем строку для возврата значения из процедуры. Справа в str то, что записано в переменной в момент вызова процедуры. Слева — новое значение str. Так как str — это var-параметр, то новое значение будет видно в вызывающей процедуре.
end;
8204:begin //в процедуру передаётся вариантный массив.
str:=str+’ №’+s;
end
end; //case (пометка, что здесь заканчивается оператор case)
end;//конец процедуры.
Процедуру prV(vv:variant; var str:string); будем вызывать из:
procedure TForm1.Button4Click(Sender: TObject);
var v,vv:variant; s,ss:string; w:word; bb:byte;
begin
s:=’это ‘;
v:=’строка ‘;
ss:=s;
prV(v,ss);//передаём в процедуру варианту строкового типа
edit1.Text:=ss;
ss:=s+’вещественное ‘;
v:=10.2;
prV(v,ss);//передаём в процедуру варианту вещественного типа
edit2.Text:=ss;
ss:=s+’целое ‘;
v:=12;
prV(v,ss);//передаём в процедуру варианту целого типа
edit3.Text:=ss;
ss:=s+’логическое ‘;
v:=true;
prV(v,ss);//передаём в процедуру варианту логического типа
edit4.Text:=ss;
ss:=s+’word (слово) ‘;
w:=9;
v:=w;
prV(v,ss);//передаём в процедуру варианту короткого целого типа
edit5.Text:=ss;
ss:=s+’дата ‘;
v:=’2020/01/02′;
prV(v,ss);//передаём в процедуру варианту типа «дата/время»
edit6.Text:=ss;
v:=8;
ss:=s+’байт ‘;
prV(v,ss);//передаём в процедуру варианту типа байт
edit7.Text:=ss;
vv:=varArrayCreate([0,2],varVariant);
vv[0]:=15;
ss:=s+’вариантный массив ‘;
prV(vv,ss);//передаём в процедуру варианту типа «вариантный массив»
edit8.Text:=ss;
end;
Результат работы программы: