最近Delphi使用的比较多了,之前一直都处于弃用状态,。,,,所以深思了一个问题
在 Delphi 中使用记录(record)来存储键值对(key-value pairs),但不确定这是否是一个好的设计选择。
type TKeyValue = record Key: string; Value: Variant; end;
然后,我可以使用动态数组或列表来管理多个键值对:
var KeyValuePairs: TArray<TKeyValue>;
或者:
var KeyValueList: TList<TKeyValue>;
问题是:
这种设计在 Delphi 中是否合理?
Variant类型是否适合存储不同类型的值(如整数、字符串、布尔值等)?是否有更好的替代方案(比如使用
TDictionary或其他数据结构)?合理性:
如果键值对数量较少且结构简单,这种设计是可行的。
但对于复杂或高性能场景,可能需要更专业的解决方案。
关于
Variant:Variant可以存储多种类型,但会带来性能开销和类型安全风险。建议考虑泛型或特定类型的替代方案。
替代方案:
使用
TDictionary<string, TValue>(来自System.Generics.Collections)更高效且类型安全。如果键值对是固定的,建议用明确的字段定义记录或类。
反正决定没有 其他语言下用的 爽 比如GO,,,,
以下是一个小例子
MapRecord = record
private
data: TArray<string>;
function escapeDataValue(value: string): string;
function getAsString(key: string; prefix: string): string;
procedure put(key: string; value: string; prefix: string); overload;
public
procedure put(key: string; value: string); overload;
procedure put(key: string; value: integer); overload;
function getString(key: string; default: string=''): string;
function getInt(key: string; default: Integer=0): Integer;
function toJSON(): string;
end;
function MapRecord.escapeDataValue(value: string): string;
begin
result := value;
result := result.Replace('\=', #4);
result := result.Replace('=', '\=');
result := result.Replace(#4, '\=');
end;
procedure MapRecord.put(key: string; value: string; prefix: string);
var
i: Integer;
begin
for i:=0 to Length(data)-1 do begin
if Copy(data[i], 2, Length(key)-1) = key+'=' then
begin
data[i] := prefix+key+'=' + escapeDataValue(value);
exit;
end;
end;
SetLength(data, Length(data)+1);
data[Length(data)-1] := prefix+key+'=' + escapeDataValue(value);
end;
procedure MapRecord.put(key: string; value: string);
begin
put(key, value, 's');end;procedure MapRecord.put(key: string; value: integer);
begin
put(key, value.ToString, 'i');
end;
function MapRecord.getAsString(key: string; prefix: string): string;
var
s: string;
i: Integer;
begin
result := '';
for s in data do
begin
if s.StartsWith(prefix+key) then
begin
i := Pos('=', s, Length(prefix+key));
if (i>0) and (i<s.Length) then
begin
result := s.Substring(i+1);
result := result.Replace('\=', '=');
end;
end;
end;
end;
function MapRecord.getString(key: string; default: string=''): string;
begin
result := getAsString(key, 's');
end;
function MapRecord.getInt(key: string; default: Integer=0): Integer;
begin
result := StrToIntDef(getAsString(key, 'i'), default);
end;
function MapRecord.toJSON(): string;
begin
//。。。。。。转换
end;使用:
function DoLogin();var
mr: MapRecord;begin
///。。。。。。。。。。。。。。。
if LoginOK then begin
mr.put('login_result', 'ok');
mr.put('user_message', 'Logged in'); end
else begin
mr.put('login_result', 'error');
mr.put('user_message', 'Login failed');
mr.put('allow_retry', 0); end;
result := mr.toJSON();
end;最后建议:
建议不要使用TArray<string>,而应当改用TArray<TPair<string, string>>或自定义的TValueRec记录类型(该记录包含两个字符串字段:name和value,并可添加语法糖修饰)。
不过除此之外:这个思路本身没有问题。但按照Delphi的惯用范式,更推荐使用TDictionary<T, S>来实现此类需求。
(翻译说明:
1. 将"definitely should"译为"应当"体现建议强度
2. "syntactical sugar"译为"语法糖"是编程术语标准译法
3. "idiomatic Delphi approach"译为"Delphi的惯用范式"准确传达语言特性
4. 使用中文技术文档常见的"字段"对应"record type"中的成员
5. 保持技术术语大小写规范(如TDictionary<T, S>保留原格式)
6. 通过"不过除此之外...但..."的转折结构完整保留原文逻辑层次




还没有评论,来说两句吧...