p1 += mult2;
p1 += add3;
forall(a,p1);
Подпрограммы в этом случае вызываются в порядке прикрепления: вначале умножение, потом сложение.
Отсоединение неприкрепленных подпрограмм не выполняет никаких действий:
p1 -= print;
Кроме того, к процедурной переменной можно прикреплять/откреплять классовые и экземплярные методы классов. В последнем случае процедурная переменная в полях объекта запоминает некоторое состояние, которое меняется между вызовами метода, связанного с этой процедурной переменной.
type
A = class
x0: integer := 1;
h: integer := 2;
procedure PrintNext;
begin
Print(x0);
x0 *= h;
end;
end;
begin
var p: procedure;
var a1 := new A();
p := a1.PrintNext;
for var i:=1 to 10 do
p;
// 1 2 4 8 16 32 64 128 256 512
end.
Подобное поведение гораздо проще реализовать с помощью захвата переменной лямбда-выражением:
begin
var x0 := 1;
var p: Action0 := procedure -> begin Print(x0); x0 *= 2 end;
for var i:=1 to 10 do
p;
end.
Файловые типы
Файл представляет собой последовательность элементов одного типа, хранящихся на диске. В PascalABC.NET имеется два типа файлов -
Для описания текстового файла используется стандартное имя типа text, бестиповые файлы имеют тип file, а для описания типизированного файла используется конструкция file of тип элементов:
var
f1: file of real;
f2: text;
f3: file;
В качества типа элементов в типизированном файле не могут фигурировать указатели, ссылочные типы, а также тип записи, содержащий ссылочные поля или указатели.
Стандартные файловые процедуры и функции описываются в пункте Процедуры и функции для работы с файлами.
Кроме того, в .NET имеется ряд классов, связанных с работой с файлами.
Эквивалентность и совместимость типов
Говорят, что типы T1 и T2 совпадают, если они имеют одно имя либо же определены в секции type в виде T1 = T2. Таким образом, в описаниях
type
IntArray = array [1..10] of integer;
IntArrayCopy = IntArray;
var
a1: IntArray;
a2: IntArrayCopy;
b1,c1: array [1..15] of integer;
b2: array [1..15] of integer;
переменные a1 и a2 и переменные b1 и c1 имеют один и тот же тип, а переменные b1 и b2 - разные типы.
Говорят, что типы T1 и T2 эквивалентны, если выполняется одно из следующих условий:
* T1 и T2 совпадают
* T1 и T2 - динамические массивы с совпадающими типами элементов
* T1 и T2 - указатели с совпадающими базовыми типами
* T1 и T2 - множества с совпадающими базовыми типами
* T1 и T2 - процедурные типы с совпадающим списком формальных параметров (и типом возвращаемого значения - для функций)
Если типы эквивалентны только если их имена совпадают, то говорят, что имеет место
Только если типы T1 и T2 эквивалентны, фактический параметр типа T1 может быть подставлен вместо формального параметра-переменной типа T2.
Говорят, что типы T1 и T2 совместимы, если выполняется одно из следующих условий:
* T1 и T2 эквивалентны
* T1 и T2 принадлежат к целым типам
* T1 и T2 принадлежат к вещественным типам
* Один из типов - поддиапазон другого или оба - поддиапазоны некоторого типа
* T1 и T2 - множества с совместимыми базовыми типами
Говорят, что значение типа T2 можно присвоить переменной типа T1 или тип T2 совместим по присваиванию с типом T1, если выполняется одно из следующих условий:
* T1 и T2 совместимы
* T1 - вещественного типа, T2 - целого
* T1 - строкового типа, T2 - символьного
* T1 - pointer, T2 - типизированный указатель
* T1 - указатель или процедурная переменная, T2=nil
* T1 - процедурная переменная, T2 - имя процедуры или функции с соответствующим списком параметров