Pascal基础(七)-Pascal泛型

it2024-03-28  50

Pascal基础(七)-Pascal泛型

前言

目前很多语言都有泛型或者类似实现

C语言比较古老,没有泛型实现C++ 有template来实现,个人对c++不懂,应该template和泛型不一样java 1995发布,2004年的1.5版本加入泛型C# 2000年发布, 2004年发布2.0加入泛型go 2009年发布, 据说2021年8月发布的 Go 1.17 中添加泛型 [https://www.oschina.net/news/116519/go-generics-next-step]

简介

泛型有时也称之参数化类型.

从2.2开始,objfpc模式{$mode objfpc}官方支持泛型,而delphi模式{$mode delphi}需要从2.6开始.之所以支持两种方言dialect仅仅因为泛型的实现比delphi官方语言早了几年.

支持部分units使用{$mode objfpc},其它units使用{$mode delphi}

FGL(Free Generics Library) 是objfpc{$mode objfpc}模式下原生fpc泛型容器集合,rtl-generics是尽力兼容delphi{$mode delphi}泛型库的功能更多的泛型容器集合,从fpc 3.0.4 可用,3.1.1+以后成为标准库之一.

FGL,rtl-generics都可以用于两种语法模式

FGL

fgl 单元入手极易.包含以下几个基本类

TFPGListTFPGObjectListTFPGInterfacedObjectListTFPGMap

代码示例

Program demo2; {$mode objfpc} Uses fgl,sysutils; Type TStudent = Class(TObject) FId : integer; FName: string; End; TStudents = specialize TFPGObjectList<TStudent>; Function GetList(i:integer): TStudents; Var c : TStudent; Begin result := TStudents.Create; For i:=1 To 10 Do Begin c := TStudent.Create; c.FId := i; c.FName := 'hello'+inttostr(i); result.Add(c); End; End; Var list : TStudents; c : TStudent; i : integer; Begin list := GetList(10); For i:=1 To list.Count Do Begin c := list[i-1]; writeln(c.Fid,',',c.Fname); End; list.Clear; list.Free; End. demo2.elf:demo2.pas ptop demo2.pas demo2.pas fpc -gh demo2.pas -odemo2.elf

自定义泛型类

如果fgl定义的泛型类不能满足需求,可以自定义泛型类

自定义泛型类定义,使用generic关键字。

type generic TList<T> = class Items: array of T; procedure Add(Value: T); end;

自定义泛型类实现

implementation procedure TList.Add(Value: T); begin SetLength(Items, Length(Items) + 1); Items[Length(Items) - 1] := Value; end;

自定义泛型类使用

Type TIntegerList = specialize TList<Integer>; TPointerList = specialize TList<Pointer>; TStringList = specialize TList<string>;

备注

理论上泛型类和一般类没有性能差异

代码示例

一个获取最大值的泛型示例

program demo3; {$mode objfpc}{$H+} type generic TFakeClass<_GT> = class class function gmax(a,b: _GT):_GT; end; TFakeClassInt = specialize TFakeClass<integer>; TFakeClassDouble = specialize TFakeClass<double>; class function TFakeClass.gmax(a,b: _GT):_GT; begin if a > b then result := a else result := b; end; begin // show max of two integers writeln( 'Integer GMax:', TFakeClassInt.gmax( 23, 56 ) ); // show max of two doubles writeln( 'Double GMax:', TFakeClassDouble.gmax( 23.89, 56.5) ); readln(); end.
最新回复(0)