105 lines
5.4 KiB
HTML
105 lines
5.4 KiB
HTML
<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>
|
||
Println(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>
|
||
Println(y.first, y.second);<br>
|
||
<b>end</b>.</code></p>
|
||
</blockquote>
|
||
<p>По окончании работы данная программа выведет 3 abc.</p>
|
||
</body>
|
||
|
||
</html>
|