加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi Generics>具有默认值的字典

发布时间:2020-12-15 09:45:56 所属栏目:大数据 来源:网络整理
导读:我希望有一个字典,当找不到搜索键时返回默认值.阅读文档: Generics.Collections.Tdictionary […]此类提供映射[…]和初始内容. 1 – 怎么样?有没有办法做到这一点ala Python:{1:’one’; 2:’两个’}? Generics.Collections.TDictionary.TryGetValue [
我希望有一个字典,当找不到搜索键时返回默认值.阅读文档:

Generics.Collections.Tdictionary
[…]此类提供映射[…]和初始内容.

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

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

2 – 如何设置此默认值?我找不到构造函数(可能我只是在错误的地方搜索过.我期待类似“构造函数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,'one');

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

    checkEquals('Default response','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.

–jeroen

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读