gpt4 book ai didi

Delphi 泛型 > 具有默认值的字典

转载 作者:行者123 更新时间:2023-12-03 15:14:23 26 4
gpt4 key购买 nike

我想要一个字典,当找不到搜索键时返回默认值。从文档中读取:

泛型.集合.Tdictionary[…]此类提供映射[…]和初始内容。

1 - 怎么办?有没有办法像 Python 一样做到这一点:{1: ‘one’; 2:'两个'} ?

Generics.Collections.TDictionary.TryGetValue[...] 如果给定的键在字典中并在 Value 中提供其值,则 TryGetValue 返回 true。否则,返回 false,并将 Value 设置为默认值类型 Tvalue。

2 - 如何设置此默认值?我找不到构造函数(可能是我刚刚搜索到了错误的位置。我期待类似“constructor Create(DefaultValue: TValue);”的内容)

所以我正在尝试实现我自己的(可能没有必要。见上文):

代码是(欢迎评论和建议!):

unit Util;

interface

uses
Generics.collections;

type

//
// Dictionary with default response
//
TDefaultDictonary<K, V> = class(TObjectDictionary<K, V>)
private
M_DefaultValue : V;

public
constructor Create(Defaultvalue : V);
destructor Destroy; reintroduce;
function GetDefaultValue : V;
function TryGetValue(const Key: K; out Value: V): Boolean;
function GetValueOf(const Key: K) : V;
end;

implementation

//
// Contructor and destructor
//
constructor TDefaultDictonary<K, V>.Create(Defaultvalue : V);
begin
inherited Create;

M_DefaultValue := Defaultvalue;
end;

destructor TDefaultDictonary<K, V>.Destroy;
begin
inherited Destroy;
end;

//
// Get the default Value
//
function TDefaultDictonary<K, V>.GetDefaultValue : V;
begin
Result := M_DefaultValue;
end;


//
// Try to get a value from the dictionary for the given key.
//
// If the value is found then "Value" holds it and the function returns true.
// If the value is not found then "Value" holds the default value and the
// function returns false.
//
function TDefaultDictonary<K, V>.TryGetValue(const Key: K; out Value: V): Boolean;
var
IsKeyFound : boolean;
DictVal : V;

begin
IsKeyFound := inherited TryGetValue(Key, DictVal);
if not IsKeyFound then begin
DictVal := M_DefaultValue;
end;

// Outputs:
Value := DictVal;
Result := IsKeyFound;
end;


//
// Get a value from the dictionary for the given key.
//
// If the value is found then the function returns it.
// If the value is not found the function returns the default value.
//
function TDefaultDictonary<K, V>.GetValueOf(const Key: K) : V;
var
DictVal : V;

begin
TryGetValue(Key, DictVal);

Result := DictVal;
end;

测试是:

unit Test_Utils;
{
Test the TDefaultDictionary functionality
}

interface

uses
Sysutils, Math, TestFramework, Util;

type

TestUtil = class(TTestCase)

public
procedure SetUp; override;
procedure TearDown; override;

published
procedure TestDefaultDictionaryGetDefaultResponse;
procedure TestDefaultDictionaryExistingKey;
procedure TestDefaultDictionaryNotExistingKey;

end;


implementation


procedure TestUtil.SetUp;
begin
end;

procedure TestUtil.TearDown;
begin
end;


procedure TestUtil.TestDefaultDictionaryGetDefaultResponse;
var
dd : TDefaultDictonary<integer, string>;

begin
dd := TDefaultDictonary<integer, string>.Create('Default response');
checkEquals('Default response', dd.GetDefaultValue);

dd.Free;
end;

procedure TestUtil.TestDefaultDictionaryExistingKey;
var
dd : TDefaultDictonary<integer, string>;
outVal : string;
isKeyFound : boolean;

begin
dd := TDefaultDictonary<integer, string>.Create('Default response');
dd.Add(1, 'My one');

checkEquals(1, dd.Count,
'One element as count');

isKeyFound := dd.TryGetValue(1, outVal);
check(isKeyFound,
'Key not found by TryGetValue');

checkEquals('My one', outVal,
'Value given by TryGetValue');

checkEquals('My one', dd[1],
'Value given by indexing as array');

dd.Free;
end;


procedure TestUtil.TestDefaultDictionaryNotExistingKey;
var
dd : TDefaultDictonary<integer, string>;
outVal : string;
isKeyFound : boolean;

begin
dd := TDefaultDictonary<integer, string>.Create('Default response');
dd.Add(1, 'one');

isKeyFound := dd.TryGetValue(2, outVal);
check(not isKeyFound,
'Key should not be found by TryGetValue');

checkEquals('Default response', outVal,
'Default Value given by TryGetValue');

checkEquals('Default response', dd.GetValueOf(2),
'Default Value given by indexing as array');

//
// It is possible to oveload the indexer operator?
// Please review or delete me !
//
//checkEquals('Default response', dd[2],
// 'Value given by indexing as array');
//

dd.Free;
end;


initialization
RegisterTest(TestUtil.Suite);
end.

这还远未完成。我希望索引器操作符也能工作(参见最后一个测试)。这可能吗?还应该实现什么?

此实现是否泄漏 M_DefaultValue(我是 Delphi 的新手)。我无法在析构函数中执行 M_DefaultValue.Free 的操作(由于构造函数的限制,不太灵活)这里可以做什么?

提前致谢,

弗朗西斯

最佳答案

在自己编写所有这些代码之前,您可能需要查看 DeHL library 中的泛型类。 .

它支持这个:

Type Support concept that defines a set of default "support classes" for each built-in Delphi types (used as defaults in collections). Custom "type support" classes can be registered for your custom data types.

--杰罗恩

关于Delphi 泛型 > 具有默认值的字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4005578/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com