W Cat - Описание языка PascalABC.NET
Скачивание начинается... Если скачивание не началось автоматически, пожалуйста нажмите на эту ссылку.
Жалоба
Напишите нам, и мы в срочном порядке примем меры.
Описание книги "Описание языка PascalABC.NET"
Описание и краткое содержание "Описание языка PascalABC.NET" читать бесплатно онлайн.
PascalABC.NET — это язык программирования Паскаль нового поколения, включающий классический Паскаль, большинство возможностей языка Delphi, а также ряд собственных расширений. Он реализован на платформе Microsoft.NET и содержит все современные языковые средства: классы, перегрузку операций, интерфейсы, обработку исключений, обобщенные классы и подпрограммы, сборку мусора, лямбда-выражения, средства параллельного программирования.
PascalABC.NET является мультипарадигменным языком: на нем можно программировать в структурном, объектно-ориентированном и функциональном стилях.
PascalABC.NET — это также простая и мощная интегрированная среда разработки, поддерживающая технологию IntelliSense, содержащая средства автоформатирования, встроенный отладчик и встроенный дизайнер форм.
begin
Result := i;
exit;
end;
end;
var x: array of string;
begin
SetLength(x,4);
x[0] := 'Ваня';
x[1] := 'Коля';
x[2] := 'Сережа';
x[3] := 'Саша';
writeln(FindFirstInArray(x,'Сережа'));
end.
При вызове обобщенной подпрограммы тип-параметр обобщения можно не указывать, поскольку компилятор выводит типы параметров шаблона по типам фактических параметров. В данном случае после выведения получено: T=string.
При выведении требуется точное соответствие типов, приведение типов не допускается. Например, при компиляции следующего кода
...
var x: array of real;
begin
SetLength(x,3);
x[0] := 1;
x[1] := 2.71;
x[2] := 3.14;
writeln(FindFirstInArray(x,1));
end.
произойдет ошибка. Причина состоит в том, что первый параметр имеет тип array of real, а второй - тип integer, что не соответствует ни одному типу T в заголовке обобщенной функции. Для решения проблемы следует либо изменить тип второго параметра на real:
FindFirstInArray(x,1.0)
либо явно после имени функции в угловых скобках указать имя типа, которым параметризован данный вызов:
FindFirstInArray&<real>(x,1)
Использование знака & здесь обязательно, поскольку в противном случае компилятор трактует знак < как <меньше<.
Обобщёнными могут быть не только обычные подпрограммы, но и методы классов, а также методы другого обобщённого класса. Например:
type
Pair<T,Q> = class
first: T;
second: Q;
function ChangeSecond<S>(newval: S): Pair<T, S>;
end;
function Pair<T,Q>.ChangeSecond<S>(newval: S): Pair<T,S>;
begin
result := new Pair<T,S>;
result.first := first;
result.second := newval;
end;
var
x: Pair<integer,real>;
y: Pair<integer,string>;
begin
x := new Pair<integer,real>;
x.first := 3;
y := x.ChangeSecond('abc');
writeln(y.first, y.second);
end.
По окончании работы данная программа выведет 3abc.
Обобщенные подпрограммы в качестве параметров
Обобщенная подпрограмма может выступать в качестве формального параметра другой обобщенной подпрограммы.
Например, в классе System.Array имеется несколько статических обобщенных методов с обобщенными подпрограммами в качестве параметров. Так, System.Array.Find имеет следующий прототип:
System.Array.FindAll<T>(a: array of T; pred: Predicate<T>): array of T;
и возвращает подмассив массива a элементов T, удовлетворяющих условию pred.
Приведем пример вызова этой функции:
function f(x: integer): boolean;
begin
Result := ;
end;
var a := Seq(1,3,6,5,8);
var b := System.Array.FindAll(a,x -> x mod 2 = 0);
Здесь возвращается массив b, содержащий все четные значения массива a в том же порядке.
Ограничения на параметры обобщенных подпрограмм и классов
По умолчанию с переменными, имеющими тип параметра обобщенного класса или подпрограммы, внутри методов обобщённых классов и обобщенных подпрограмм можно делать лишь ограниченный набор действий: присваивать и сравнивать на равенство (отметим, что в NET сравнение на равенство внутри обобщений запрещено!).
Например, данный код будет работать:
function Eq<T>(a,b: T): boolean;
begin
Result := a = b;
end;
Можно также использовать присваивание переменной, имеющей тип параметра обобщенного класса или подпрограммы, значение по умолчанию, используя конструкцию default(T) - значение по умолчанию для типа T (nil для ссылочных типов и нулевое значение для размерных типов):
procedure Def<T>(var a: T);
begin
a := default(T);
end;
Однако, данный код
function Sum<T>(a,b: T): T;
begin
Result := a + b;
end;
вызовет ошибку компиляции до инстанцирования (создания экземпляра с конкретным типом). Такое поведение в .NET кардинально отличается от шаблонов в C++, где в коде шаблона можно использовать любые операции с шаблонными параметрами, и ошибка может произойти только в момент инстанцирования с конкретным типом.
Чтобы разрешить использование некоторых действий с переменными, имеющими тип параметра обобщенного класса или подпрограммы, используются ограничения на обобщенные параметры, задаваемые в секции where после заголовка подпрограммы или класса:
type
MyPair<T> = class
where T: System.ICloneable;
private
x,y: T;
public
constructor (x,y: T);
begin
Self.x := x;
Self.y := y;
end;
function Clone: MyPair;
begin
Result := new MyPair<T>(x.Clone,y.Clone);
end;
end;
В секции where через запятую перечисляются следующие ограничения:
На 1 месте: слово class или слово record или имя класса-предка.
На 2 месте: список реализуемых интерфейсов через запятую.
На 3 месте: слово constructor, указывающее, что данный тип должен иметь конструктор по умолчанию.
При этом каждое из мест, кроме одного, может быть пустым.
Для каждого типа-параметра может быть своя секция where, каждая секция where завершается точкой с запятой.
Пример. Обобщенная функция поиска минимального элемента в массиве. Элементы должны реализовывать интерфейс IComparable<T>.
function MinElem<T>(a: array of T): T;
where T: IComparable<T>;
begin
var min: T := a[0];
for var i := 1 to a.Length-1 do
if min.CompareTo(a[i])<0 then
min := a[i];
Result := max;
end;
К сожалению, нет возможности использовать операцию <, поскольку операции не входят в интерфейсы.
Элементы функционального программирования
Лямбда-выражения
Лямбда-выражение - это выражение специального вида, которое на этапе компиляции заменяется на имя подпрограммы, соответствующей лямбда-выражению и генерируемой компилятором на лету.
Здесь излагается полный синтаксис лямбда-выражений.
Здесь рассказывается о захвате лямбда-выражением переменных из внешнего контекста.
Лямбда-выражения запрещается использовать при инициализации полей класса или записи, внутри вложенных подпрограмм, в подпрограмме при наличии вложенной подпрограммы, в разделе инициализации модуля.
Синтаксис лямбда-выражений достаточно сложен и в данном пункте иллюстрируется на примерах.
Пример 1.
var f: integer -> integer := x -> x*x;
f(2);
Запись x -> x является лямбда-выражением, представляющем собой функцию с одним параметром x типа integer, возвращающую x*x типа integer. По данной записи компилятор генерирует следующий код:
function #fun1(x: integer): integer;
begin
Result := x*x;
end;
...
var f: integer -> integer := #fun1;
f(2);
Здесь #fun1 - это имя, генерируемое компилятором. Кроме того, код функции #fun1 также генерируется компилятором.
Пример 2. Фильтрация четных
Обычно лямбда-выражение передаётся как параметр подпрограммы. Например, в следующем коде
var a := Seq(3,2,4,8,5,5);
a.Where(x -> x mod 2 = 0).Print;
лямбда-выражение x -> x mod 2 = 0 задаёт условие отбора чётных чисел из массива a.
Пример 3. Сумма квадратов
var a := Seq(1,3,5);
writeln(a.Aggregate(0,(s,x)->s+x*x));
Иногда необходимо явно задавать тип параметров в лямбда-выражении.
Пример 4. Выбор перегруженной версии процедуры с параметром-лямбдой.
procedure p(f: integer -> integer);
begin
write(f(1));
end;
procedure p(f: real -> real);
begin
write(f(2.5));
end;
begin
p((x: real)->x*x);
end.
В данном примере вызов p(x -> x) вызовет ошибку компиляции, потому что компилятор не может выбрать, какую версию процедуры p выбирать. Задание типа параметра лямбды помогает устранить эту неоднозначность.
Пример 5. Лямбда-процедура.
procedure p(a: integer -> ());
begin
a(1)
end;
begin
p(procedure(x) -> write(x));
end.
Захват переменных в лямбда-выражении
Лямбда-выражение может использовать переменные из внешнего контекста. Такие переменные называются захваченными лямбда-выражением.
Пример 1. Захват переменной в запросе Select.
begin
var a := Seq(2,3,4);
var z := 1;
var q := a.Select(x->x+z);
q.Println;
z := 2;
q.Println;
end.
Здесь лямбда-выражение x->x+z захватывает внешнюю переменную z. Важно заметить, что при изменении значения переменной z запрос a.Select(x->x+z), хранящийся в переменной q, выполняется с новым значением z.
Пример 2. Накопление суммы во внешней переменной.
begin
var sum := 0;
var AddToSum: integer -> () := procedure (x) -> begin sum += x; end;
AddToSum(1);
AddToSum(3);
AddToSum(5);
Подписывайтесь на наши страницы в социальных сетях.
Будьте в курсе последних книжных новинок, комментируйте, обсуждайте. Мы ждём Вас!
Похожие книги на "Описание языка PascalABC.NET"
Книги похожие на "Описание языка PascalABC.NET" читать онлайн или скачать бесплатно полные версии.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.
Отзывы о "W Cat - Описание языка PascalABC.NET"
Отзывы читателей о книге "Описание языка PascalABC.NET", комментарии и мнения людей о произведении.