В мире программирования на Pascal и Delphi часто возникает необходимость работать с ассоциативными массивами, где доступ к элементам осуществляется по строковому ключу. В этой статье мы рассмотрим, как реализовать подобную функциональность, используя свойства классов и другие подходы.
Проблема строкового индекса
Как отметил пользователь Weiss в обсуждении, стандартные массивы в Pascal не поддерживают строковые индексы напрямую. Однако современные версии Delphi и Free Pascal предоставляют несколько способов эмуляции этого поведения.
Рассмотрим пример кода, который вызывает вопрос:
someVariable := myHomeMadeDictionary[myKey]
Как реализовать такой синтаксис для собственного класса?
Решение через свойства класса
Основное решение, предложенное в обсуждении - использование свойств класса с параметрами. Вот как это можно реализовать:
type
TMyDictionary = class
private
FKeys: array of string;
FValues: array of Integer; // или любой другой тип данных
function GetValue(const AKey: string): Integer;
procedure SetValue(const AKey: string; AValue: Integer);
public
property Values[const AKey: string]: Integer read GetValue write SetValue; default;
end;
implementation
function TMyDictionary.GetValue(const AKey: string): Integer;
var
i: Integer;
begin
for i := 0 to High(FKeys) do
if FKeys[i] = AKey then
Exit(FValues[i]);
raise Exception.Create('Key not found');
end;
procedure TMyDictionary.SetValue(const AKey: string; AValue: Integer);
var
i: Integer;
begin
for i := 0 to High(FKeys) do
if FKeys[i] = AKey then
begin
FValues[i] := AValue;
Exit;
end;
// Если ключ не найден, добавляем новую пару
SetLength(FKeys, Length(FKeys) + 1);
SetLength(FValues, Length(FValues) + 1);
FKeys[High(FKeys)] := AKey;
FValues[High(FValues)] := AValue;
end;
Использование:
var
Dict: TMyDictionary;
begin
Dict := TMyDictionary.Create;
try
Dict['first'] := 10; // Установка значения
Writeln(Dict['first']); // Получение значения
finally
Dict.Free;
end;
end.
Альтернативные решения
1. Использование TDictionary из Generics.Collections
Для большинства практических задач лучше использовать стандартный TDictionary из модуля Generics.Collections:
uses
System.Generics.Collections;
var
Dict: TDictionary<string, Integer>;
begin
Dict := TDictionary<string, Integer>.Create;
try
Dict.AddOrSetValue('first', 10);
Writeln(Dict['first']);
finally
Dict.Free;
end;
end.
2. Использование TStringList
Для простых случаев можно использовать TStringList с поддержкой пар "ключ-значение":
var
SL: TStringList;
begin
SL := TStringList.Create;
try
SL.Values['first'] := '10';
Writeln(SL.Values['first']);
finally
SL.Free;
end;
end.
3. Использование FGL (Free Pascal Generic Library)
В Free Pascal доступен более легковесный модуль FGL:
uses
fgl;
type
TStringToIntMap = specialize TFPGMap<string, Integer>;
var
Map: TStringToIntMap;
begin
Map := TStringToIntMap.Create;
try
Map['first'] := 10;
Writeln(Map['first']);
finally
Map.Free;
end;
end.
Производительность и выбор решения
Как отметил Thaddy в обсуждении, важно понимать компромиссы между различными подходами:
Собственная реализация (первый пример) - максимальный контроль, но требует больше кода и может быть менее эффективной.
Generics.Collections - стандартное решение для Delphi, хорошо оптимизировано.
FGL - легковесная альтернатива для Free Pascal.
TStringList - простое решение для базовых задач.
Заключение
Реализация строкового индекса в Pascal возможна несколькими способами. Выбор конкретного метода зависит от требований проекта, необходимости совместимости с Delphi и предпочтений разработчика. Для большинства случаев рекомендуется использовать стандартные классы из Generics.Collections или FGL, но понимание принципов работы "под капотом" (как в первом примере) всегда полезно для профессионального роста.
Примеры кода в этой статье демонстрируют, как можно эмулировать поведение ассоциативных массивов с строковыми ключами в Object Pascal, сохраняя при этом читаемость и удобство использования кода.
В статье рассматриваются методы реализации ассоциативных массивов со строковыми ключами в Free Pascal и Delphi, включая использование свойств классов, TDictionary, TStringList и FGL.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS