<?xml version="1.0" encoding="utf-8"?> 
<rss version="2.0"
  xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
  xmlns:atom="http://www.w3.org/2005/Atom">

<channel>

<title>Математик среди биологов: заметки с тегом дельфи</title>
<link>https://antonlyakh.ru/blog/tags/delphi/</link>
<description>Я немного умею складывать, но от вычитания у меня всегда кружится голова</description>
<author>Антон Лях</author>
<language>ru</language>
<generator>E2 (v3559; Aegea)</generator>

<itunes:owner>
<itunes:name>Антон Лях</itunes:name>
<itunes:email></itunes:email>
</itunes:owner>
<itunes:subtitle>Я немного умею складывать, но от вычитания у меня всегда кружится голова</itunes:subtitle>
<itunes:image href="" />
<itunes:explicit></itunes:explicit>

<item>
<title>Ассоциативный массив в старых версиях Дельфи</title>
<guid isPermaLink="false">451</guid>
<link>https://antonlyakh.ru/blog/all/associativny-massiv-v-staryh-versiyah-delfi/</link>
<pubDate>Tue, 19 Apr 2022 11:08:05 +0300</pubDate>
<author>Антон Лях</author>
<comments>https://antonlyakh.ru/blog/all/associativny-massiv-v-staryh-versiyah-delfi/</comments>
<description>
&lt;p&gt;В Королевстве Дельфи много лет назад Дмитрий Рябов предложил &lt;a href="http://www.delphikingdom.com/asp/viewitem.asp?catalogid=868"&gt;реализацию ассоциативных массивов&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;«На практике часто возникает потребность сохранять и обрабатывать данные в массивах, осуществляя доступ к элементам не по индексу, а по ключу. Для этого используются ассоциативные массивы, которые есть, например, во многих скриптовых языках. В &lt;abbr&gt;Delphi&lt;/abbr&gt; на уровне языка такая структура отсутствует. В качестве замены часто используются контейнерные классы &lt;abbr&gt;TStringList&lt;/abbr&gt;, &lt;abbr&gt;TParams&lt;/abbr&gt; и т. п., но они весьма неудобны в использовании и недостаточно функциональны. К тому же появляется необходимость заботиться об уничтожении экземпляра класса, что зачастую порождает лишние &lt;abbr&gt;try..finally..end&lt;/abbr&gt;.»&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;В чем фишка реализации.&lt;/p&gt;
&lt;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;«Удобное использование, неплохая производительность, отсутствие небходимости принудительного уничтожения, нескольно представлений одного массива, использование ключей разных типов, наличие функций итератора, удобное использование многомерных массивов.»»&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;Я иногда ее использую в своих проектах и всегда опасаюсь, что текст с примерами будет окончательно потерян. Потому решил воспроизвести его здесь.&lt;/p&gt;
&lt;hr /&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class=""&gt;program Example;
{$APPTYPE CONSOLE}
uses
  Arrays;

procedure Main;
var
  I: IIntArray;
  S: IStrArray;
  V: IVarArray;
  M: IMltArray;

begin
  // создаём массив и получаем представление в целых числах
  I := CreateArray;

  // заполняем
  I['a'] := 5;
  I['b'] := 1;
  I['c'] := 4;
  I['d'] := 2;
  I['e'] := 3;

  // выводим
  WriteLn('Original array');
  I.First;
  while not I.Eof do
  begin
    WriteLn('[', I.CurrentKey, '] = ', I.CurrentValue);
    I.Next;
  end;

  // сортируем
  I.Sort;

  // наблюдаем результат
  WriteLn('Sorted array');
  I.First;
  while not I.Eof do
  begin
    WriteLn('[', I.CurrentKey, '] = ', I.CurrentValue);
    I.Next;
  end;

  // создаём строковое представление
  S := I.Instance;

  // наблюдаем результат
  WriteLn('Two views of one array');
  S.First;
  while not S.Eof do
  begin
    WriteLn('[', S.CurrentKey, '] + ''10'' = ', S.CurrentValue + '10');
    WriteLn('[', I.CurrentKey, '] + 10 = ', I.CurrentValue + 10);
    S.Next;
  end;

  // создаём вариантное представление
  V := S.Instance;
  V.Clear;
  V['integer'] := 10;
  V['string'] := '10';

  // наблюдаем результат
  WriteLn('Variant type conversion');
  V.First;
  while not V.Eof do
  begin
    WriteLn('[', V.CurrentKey, '] + 10 = ', V.CurrentValue + 10);
    WriteLn('[', V.CurrentKey, '] + ''10'' = ', V.CurrentValue + '10');
    V.Next;
  end;

  // используем ключи разных типов, но одного значения
  S.Clear;
  S[False] := 'boolean';
  S[0] := 'integer';
  S[0.0] := 'float';
  S['0'] := 'string';

  // наблюдаем результат
  WriteLn('Variant type keys ;)');
  S.First;
  while not S.Eof do
  begin
    WriteLn('[', S.CurrentKey, '] = ', S.CurrentValue);
    S.Next;
  end;

  // создаём ещё одно представление, на этот раз - многомерное
  M := V.Instance;
  M.Clear;

  // заполняем матрицу
  M['A']['a'].AsInteger := 1;
  M['A']['b'].AsInteger := 2;
  M['A']['c'].AsInteger := 3;
  M['B']['a'].AsInteger := 4;
  M['B']['b'].AsInteger := 5;
  M['B']['c'].AsInteger := 6;
  M['C']['a'].AsInteger := 7;
  M['C']['b'].AsInteger := 8;
  M['C']['c'].AsInteger := 9;

  // выводим матрицу
  WriteLn('Multidimensional array');
  M.First;
  while not M.Eof do
  begin
    M.CurrentValue.First;
    while not M.CurrentValue.Eof do
    begin
      WriteLn('[', M.CurrentKey, ',', M.CurrentValue.CurrentKey, '] = ',
        M.CurrentValue.CurrentValue.AsInteger);
      M.CurrentValue.Next;
    end;
    M.Next;
  end;

  // перед возвратом все созданные массивы автоматически удаляются
  WriteLn('Arrays is free');
end;

var
  L: Integer;
begin
  L := AllocMemSize;
  Main;
  // проверка утечки памяти
  WriteLn('Memory leak: ', AllocMemSize - L, ' bytes');
  ReadLn;
end.&lt;/code&gt;&lt;/pre&gt;&lt;hr /&gt;
&lt;p&gt;&lt;b&gt;&lt;a href="http://www.delphikingdom.com/zip/arrays.zip"&gt;Скачать исходники из Королевства&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;a href="https://stackoverflow.com/a/51830939/1615266"&gt;Посмотреть рекомендацию оссоциативного массива&lt;/a&gt;&lt;/b&gt; на Стакэксчендже .&lt;/p&gt;
</description>
</item>

<item>
<title>Директива reintroduce в Дельфи</title>
<guid isPermaLink="true">https://antonlyakh.ru/blog/all/direktiva-reintroduce-v-delfi/</guid>
<link>https://antonlyakh.ru/blog/all/direktiva-reintroduce-v-delfi/</link>
<pubDate>Mon, 13 Aug 2018 15:32:10 +0300</pubDate>
<author>Антон Лях</author>
<comments>https://antonlyakh.ru/blog/all/direktiva-reintroduce-v-delfi/</comments>
<description>
&lt;p&gt;Узнал, что в Дельфи есть директива &lt;b&gt;reintroduce&lt;/b&gt;. Она говорит компиляторуо том, что не надо возмущаться, когда в родственных классах определены функции с одинаковыми именами, но разным набором параметров.&lt;/p&gt;
&lt;p&gt;Здесь компилятор напомнит, что в коде непорядок:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="delphi"&gt;
type TFish = class
  procedure swim(); virtual;
end;

type TBoneFish = class(TFish)
  procedure swim(direction : TVector); overload; // Method 'swim' hides virtual method of base type TFish.
end;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;А здесь все стало правильно:&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="delphi"&gt;
type TFish = class
  procedure swim(); virtual;;
end;

type TBoneFish = class(TFish)
  procedure swim(direction : TVector); reintroduce; overload;
end;
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;В основном коде можно вызывать оба метода.&lt;/p&gt;
&lt;pre class="e2-text-code"&gt;&lt;code class="pascal"&gt;
  bone_fish.swim(); // куда-то плывем
  bone_fish.swim( to_nutritious_crustacean ); // плывем за питательным рачком
&lt;/code&gt;
&lt;/pre&gt;
</description>
</item>


</channel>
</rss>