/
n-dimens
/
pascalabcnet
Обзор
Документация
Войти
/
n-dimens
/
pascalabcnet
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
PABCNetHelp/LangGuide/Generics/generic_sub.html
104 строки
5 KB
samuraiGH
adding working-tree-encoding attribute (#3325)
07 ноя 2025, 16:12
Не верифицирован
07 ноя 2025, 16:12
cf1fd29
Код
Авторство
О чём код?
<html> <head> <object type="application/x-oleobject" classid="clsid:1e2a7bd0-dab9-11d0-b93a-00c04fc99f9e"> </object> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <title></title> <link rel="StyleSheet" href="../../default.css"> </head> <body> <H1>Обобщенные подпрограммы: обзор </H1> <p>Обобщенной подпрограммой (generic) называется подпрограмма, параметризованная одним или несколькими типами. Подпрограмма образуется из обобщенной подпрограммы подстановкой конкретных типов в качестве параметров. Параметры указываются после имени подпрограммы в угловых скобках. </p> <p>Например, следующая обобщённая функция параметризована одним параметром:</p> <blockquote> <p><code><b>function</b> FindFirstInArray<T>(a: <b>array</b> <b>of</b> T; val: T): integer;<br> <b>begin</b><br> <span lang="en-us">R</span>esult := -1;<br> <b>for </b><span lang="en-us"><b>var</b> </span>i:=0 <b>to</b> a.Length-1 <b>do</b><br> <b>if</b> a[i]=val <b>then</b><br> <b>begin</b><br> <span lang="en-us">R</span>esult := i;<br> <span lang="en-us"> </span>exit;<br> <span lang="en-us"> </span><b>end</b>;<br> <b>end</b>;</code></p> <p><code><b>var</b><span lang="en-us"> </span>x: <b>array</b> <b>of</b> string;</code></p> <p><code><b>begin</b><br> <span lang="en-us"> </span>SetLength(x,4);<br> <span lang="en-us"> </span>x[0] := 'Ваня';<br> <span lang="en-us"> </span>x[1] := 'Коля';<br> <span lang="en-us"> </span>x[2] := 'Сережа';<br> <span lang="en-us"> </span>x[3] := 'Саша';<br> <span lang="en-us"> </span>writeln(FindFirstInArray(x,'Сережа'));<br> <b>end</b>.</code></p> </blockquote> <p>При вызове обобщенной подпрограммы тип-параметр обобщения можно не указывать, поскольку компилятор <font color="#FF0000"><i><b>выводит</b></i></font> типы параметров шаблона по типам фактических параметров. В данном случае после выведения получено: <code>T=string</code>. </p> <p>При выведении требуется точное соответствие типов, приведение типов не допускается. Например, при компиляции следующего кода </p> <blockquote> <p><code>...<b><br> var</b> x: <b>array</b> <b>of</b> real;</code></p> <p><code><b>begin</b><br> SetLength(x,3);<br> x[0] := 1;<br> x[1] := 2.71;<br> x[2] := 3.14;<br> writeln(FindFirstInArray(x,1));<br> <b>end</b>.</code></p> </blockquote> <p>произойдет ошибка. Причина состоит в том, что первый параметр имеет тип <span lang="en-us">array of real</span>, а второй - тип <span lang="en-us"> integer</span>, что не соответствует ни одному типу <span lang="en-us">T </span> в заголовке обобщенной функции. Для решения проблемы следует либо изменить тип второго параметра на <span lang="en-us">real</span>:</p> <blockquote> <p><code>FindFirstInArray(x,1.0)</code></p> </blockquote> <p>либо явно после имени функции в угловых скобках указать имя типа, которым параметризован данный вызов:</p> <blockquote> <p><code>FindFirstInArray&<real>(x,1)</code></p> </blockquote> <p>Использование знака <span lang="en-us">& </span>здесь обязательно, поскольку в противном случае компилятор трактует знак <span lang="en-us">< </span>как "меньше".</p> <p>Обобщёнными могут быть не только обычные подпрограммы, но и методы классов, а также методы другого обобщённого класса. Например:</p> <blockquote> <p><code><b>type</b><br> Pair<T,Q> = <b>class</b><br> first: T;<br> second: Q;<br> <b> function</b> ChangeSecond<S>(newval: S): Pair<T, S>;<br> <b> end</b>;</code></p> <p><code><b>function</b> Pair<T,Q>.ChangeSecond<S>(newval: S): Pair<T,S>;<br> <b>begin</b><br> result := <b>new</b> Pair<T,S>;<br> result.first := first;<br> result.second := newval;<br> <b>end</b>;</code></p> <p><code><b>var</b><br> x: Pair<integer,real>;<br> y: Pair<integer,string>;<b><br> begin</b><br> x := <b>new</b> Pair<integer,real>;<br> x.first := 3;<br> y := x.ChangeSecond('abc');<br> writeln(y.first, y.second);<br> <b>end</b>.</code></p> </blockquote> <p>По окончании работы данная программа выведет 3abc.</p> </body> </html>