其他语言

位置:IT落伍者 >> 其他语言 >> 浏览文章

Delphi2009初体验-语言篇-体验泛型(二)


发布日期:2024年06月26日
 
Delphi2009初体验-语言篇-体验泛型(二)

体验泛型数组

体验泛型方法

体验自定义泛型类

体验泛型约束条件

类类型约束条件

对象类型约束条件

构造函数约束条件

值类型约束条件

多约束条件

多模板类型分别约束条件

嵌套约束条件

关于特化与偏特化

十一 总结

由于正式版还没有发出官方的帮助文档也没有洩露所以我没有办法验证Delphi对泛型的支持到何种程度了大家对泛型都很熟悉具体细节我就不多说了下面将贴出一些代码用来验证Delphi对泛型的支持并验证是否通过

体验泛型数组

program TestGenericArray;

{$APPTYPE CONSOLE}

uses

SysUtils;

type

TArr<T> = array of T;

var

arr: TArr<Integer>;

n: Integer;

begin

Setlength(arr );

for n := to do

begin

arr[n] := n;

end;

end

体验泛型方法

Delphi不支持全局泛型方法泛型方法只能置于类内或者嵌套在方法内或者成为类的静态方法

以下代码将打印出传入泛型变量的地址

program TestGenericArray;

{$APPTYPE CONSOLE}

uses

SysUtils;

type

TGeneric = class

class procedure PrintAddress<T>(aVal: T);

end;

var

n: Integer;

{ TGeneric }

class procedure TGenericPrintAddress<T>(aVal: T);

begin

Writeln(Integer(@aVal));

end;

begin

n := ;

TGenericPrintAddress<Integer>(n);

end

体验自定义泛型类

program TestGenericClass;

{$APPTYPE CONSOLE}

uses

SysUtils;

type

TGenericsClass<T> = class

private

fValue: T;

public

constructor Create(aValue: T); virtual;

property Value: T read fValue write fValue;

end;

var

gc: TGenericsClass<Integer>;

{ TGenericsClass<T> }

constructor TGenericsClass<T>Create(aValue: T);

begin

fValue := aValue;

end;

begin

gc := TGenericsClass<Integer>Create();

Writeln(gcValue);

FreeAndNil(gc);

Readln;

end

体验泛型约束条件

以下通过代码针对泛型类对Delphi所支持的泛型约束条件进行验证

类类型约束条件

约束模板类型T只能为类类型

program TestGenericClass;

{$APPTYPE CONSOLE}

uses

SysUtils;

type

TGenericsClass<T: class> = class// 注意在此进行约束

private

fValue: T;

public

constructor Create(aValue: T); virtual;

property Value: T read fValue write fValue;

end;

var

gc: TGenericsClass<TObject>;

{ TGenericsClass<T> }

constructor TGenericsClass<T>Create(aValue: T);

begin

fValue := aValue;

end;

begin

gc := TGenericsClass<TObject>Create(nil);

Writeln(gcValue = nil);

FreeAndNil(gc);

Readln;

end

对象类型约束条件

约束T只能为某一个对象类型

program TestGenericArray;

{$APPTYPE CONSOLE}

uses

SysUtils

Classes

Contnrs;

type

TGenericsClass<T: TList> = class// 注意在此进行约束

private

fValue: T;

public

constructor Create(aValue: T); virtual;

property Value: T read fValue write fValue;

end;

var

gc: TGenericsClass<TObjectList>;

{ TGenericsClass<T> }

constructor TGenericsClass<T>Create(aValue: T);

begin

fValue := aValue;

end;

begin

gc := TGenericsClass<TObjectList>Create(nil);

Writeln(gcValue = nil);

FreeAndNil(gc);

Readln;

end

构造函数约束条件

大家都知道在C#中可以使用 T where new() 对泛型模板类型进行构造函数的约束指明 类型T 必须有一个可见的构造函数

在D我也发现有这样的特性

TGeneric<T: constructor> = class

public

constructor Create; virtual;

end;

约束 constructor表明T必须拥有可见的构造函数

但是我在使用以下代码时编译器总是提示编译不通过

var

t: T;

begin

t := TCreate;

end;

获取是另外一种写法?我没有尝试出来需要等官方正式版出来才能确认

值类型约束条件

Delphi的泛型约束不提供值类型约束条件TGenericsClass<T Integer> = class这样的约束编译器是不支持的所以像c++中template <Tint S> class TBuf这样的约束在Delphi中行不通

多约束条件

与C#类似Delphi的多约束条件用来约束T既满足一个类型又满足一个接口

program TestGenericArray;

{$APPTYPE CONSOLE}

uses

SysUtils

Classes

Windows

Contnrs;

type

IInt = Interface

procedure Test;

End;

TImp = class(TInterfacedObject IInt)

public

procedure Test;

end;

TGenericsClass<T: class IInt> = class// 注意在此进行约束

private

fValue: T;

public

constructor Create(aValue: T); virtual;

property Value: T read fValue write fValue;

end;

var

gc: TGenericsClass<TImp>;

{ TGenericsClass<T> }

constructor TGenericsClass<T>Create(aValue: T);

begin

fValue := aValue;

end;

{ TImp }

procedure TImpTest;

begin

end;

begin

gc := TGenericsClass<TImp>Create(nil);

Writeln(gcValue = nil);

FreeAndNil(gc);

Readln;

end

多模板类型分别约束条件

有两个模板类型TT要使用不同的约束分别约束两个模板类型可以使用以下方法

type

TGenericsClass<T: class; T: TList> = class// 注意在此进行约束将两个模板类型分开进行分别约束

private

end;

嵌套约束条件

Delphi的泛型约束条件对嵌套约束条件处理的很好

TFelix<T> = class

public

end;

TGenericsClass<T: class; T: TFelix<T>> = class// 注意在此进行约束将两个模板类型分开进行分别约束

private

end;

关于特化和偏特化

谢谢网友装配脑袋的提醒我试了很多方法都没有迹象表明D支持C++中模板的特化和偏特化或者D用其他形式的语法表示特化与偏特化导致我没有试验出来

十一总结

总体上来说D从泛型的角度出发做得已经非常不错了已经非常接近C#甚至D还提供类似于C#的关键字default来获取泛型类型T的默认值(值类型置引用类型为空指针)

在接下来的章节里我会向大家介绍D的其他新体验匿名函数和反射(比RTTI更强大)的支持

               

上一篇:Delphi把流中的字符串转换为UTF格式

下一篇:用Delphi制作录音程序