ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Delphi 新语法:泛型

2022-09-14 12:05:16  阅读:239  来源: 互联网

标签:begin end Delphi Arr TObject TForm1 语法 Caption 泛型


  这里的新语法一般指Delphi7不支持的语法,高版本中会经常遇到,所以花一点时间学会使用它。泛型是一种特殊的类型。你不用一开始就指明参数的具体类型,而是先定义一个类型变量,在使用的时候再确定参数的具体类型。准备从万一博客中学习,节约翻找资料的时间。

最简单的泛型

一开始我们看下Tbyte类型的定义
继续看一下类型TBytes是如何定义出来的.
首先:
type TArray<T> = array of T;
然后:
type TBytes = TArray<Byte>;
TBytes为标准的字节泛型,深一步也就是字节数组.
其实就相当于TBytes = array of Byte;Delphi7没有泛型概念,可以这么定义.

  首先定义一个泛型数组TArr<T> = array[0..9] of T,后面声明变量的时候可以吧TArr<T>尖括号中的T换成想要的类型,可以是整形、字符串、浮点、数据结构、类等等。

implementation

{$R *.dfm}
type
  TArr<T> = array[0..9] of T; {定义一个泛型数组}
  {虽然大家习惯用 T 来泛指其他类型, 但使用其他合法的标识符也是可以的。
  简单来说就是粗范围的定义一个T,后面声明变量的时候可以自己修改变量类型。}

procedure TForm1.Button1Click(Sender: TObject);
var
  Arr: TArr<Integer>;
  i: Integer;
begin
  for i := Low(Arr) to High(Arr) do
    Arr[i] := i * i;

  Memo1.Clear;
  for i := Low(Arr) to High(Arr) do
    Memo1.Lines.Add(Format('Arr[%d] = %d', [i, Arr[i]]));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  Arr: TArr<string>;
  i: Integer;
begin
  for i := Low(Arr) to High(Arr) do
    //重复某个字符3次
    Arr[i] := StringOfChar(Char(i + 97), 3);

  Memo1.Clear;
  for i := Low(Arr) to High(Arr) do
    Memo1.Lines.Add(Format('Arr[%d] = %s', [i, Arr[i]]));
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  Arr: TArr<Single>;
  i: Integer;
begin
  for i := Low(Arr) to High(Arr) do
    Arr[i] := 100 / (i + 1);

  Memo1.Clear;
  for i := Low(Arr) to High(Arr) do
    Memo1.Lines.Add(Format('Arr[%d] = %f', [i, Arr[i]]));
end;

procedure TForm1.Button4Click(Sender: TObject);
var
  Arr: TArr<TPoint>;
  i: Integer;
begin
  for i := Low(Arr) to High(Arr) do
    Arr[i] := Point(i, i * 2);

  Memo1.Clear;
  for i := Low(Arr) to High(Arr) do
    Memo1.Lines.Add(Format('Arr[%d] = (%d,%d)', [i, Arr[i].X, Arr[i].Y]));
end;

procedure TForm1.Button5Click(Sender: TObject);
var
  Arr: TArr<TButton>;
  i: Integer;
begin
  for i := Low(Arr) to High(Arr) do
  begin
    Arr[i] := TButton.Create(Self);
    //合并字符串
    Arr[i].Name := Concat('Btn', IntToStr(i + 1));
  end;

  Memo1.Clear;
  for i := Low(Arr) to High(Arr) do
    Memo1.Lines.Add(Format('Arr[%d] is %s', [i, Arr[i].Name]));

  for i := Low(Arr) to High(Arr) do
    Arr[i].Free;
end;

泛型类TList

想要使用TList<T>必须先引用泛型容器单元Generics.Collections

//引用新增的泛型容器单元
uses
  Generics.Collections;

//定义一个泛型 TList 类, 这指定了要用于 string}
var
  List: TList<string>;
  str: string = 'Test';

//建立
procedure TForm1.FormCreate(Sender: TObject);
begin
  List := TList<string>.Create;

  Memo1.Clear;
  Edit1.Text := str;
  Button1.Caption := Button1.Caption + ' 显示';
  Button2.Caption := Button2.Caption + ' 添加';
  Button3.Caption := Button3.Caption + ' 插入';
  Button4.Caption := Button4.Caption + ' 删除1';
  Button5.Caption := Button5.Caption + ' 删除2';
  Button6.Caption := Button6.Caption + ' 查找';
  Button7.Caption := Button7.Caption + ' 排序';
  Button8.Caption := Button8.Caption + ' 翻转';
  Button9.Caption := Button9.Caption + ' 清空';
  Button10.Caption := Button10.Caption + ' 添加数组';
end;

//释放
procedure TForm1.FormDestroy(Sender: TObject);
begin
  List.Free;
end;

procedure TForm1.Edit1Change(Sender: TObject);
begin
  if Edit1.Text <> '' then str := Edit1.Text;
end;

//显示
procedure TForm1.Button1Click(Sender: TObject);
var
  i: Integer;
begin
  Memo1.Clear;
  for i := 0 to List.Count - 1 do
    Memo1.Lines.Add(List[i]);  {List[i] = List.Item[i]}
  Text := Format('当前总数: %d', [List.Count]);
end;

//添加
procedure TForm1.Button2Click(Sender: TObject);
begin
  List.Add(str);
  Button1.Click; {刷新显示}
end;

//插入, 譬如插入在最前面
procedure TForm1.Button3Click(Sender: TObject);
begin
  List.Insert(0, str);
  Button1.Click;
end;

//根据序号删除, 譬如删除第一个数据
procedure TForm1.Button4Click(Sender: TObject);
begin
  List.Delete(0);
  Button1.Click;
end;

//根据内容删除, 譬如删除第一个数据
procedure TForm1.Button5Click(Sender: TObject);
var
  s: string;
begin
  s := List[0];
  List.Remove(s);
  Button1.Click;
end;

//查找
procedure TForm1.Button6Click(Sender: TObject);
var
  n: Integer;
begin
  n := List.IndexOf(str); {LastIndexOf 是从后面找; 也可用 List.Contains(str) 判断是否包含 str}
  if n = -1 then
    ShowMessage('没找到')
  else
    ShowMessageFmt('%s 是第 %d 个', [str, n+1]);
end;

//排序
procedure TForm1.Button7Click(Sender: TObject);
begin
  List.Sort;
  Button1.Click;
end;

//翻转
procedure TForm1.Button8Click(Sender: TObject);
begin
  List.Reverse;
  Button1.Click;
end;

//清空
procedure TForm1.Button9Click(Sender: TObject);
begin
  List.Clear;
  Button1.Click;
end;

//添加数组
procedure TForm1.Button10Click(Sender: TObject);
const
  arr: array[0..2] of string = ('CodeGear', 'Delphi', '2009');
begin
  List.Add('Embarcadero');
  List.AddRange(arr);
  Button1.Click;
end;

泛型类TQueue

TQueue 队列类主要有三个方法、一个属性:
Enqueue(入列)、Dequeue(出列)、Peek(查看下一个要出列的元素);
Count(元素总数). 队列类是采用先进先出原则。

implementation

{$R *.dfm}

uses
  System.Generics.Collections;

type
  TRec = record
    Name: string;
    Age: Word;
  end;

var
  Queue: Tqueue<TRec>;

procedure TForm1.Button1Click(Sender: TObject);
var
  rec: TRec;
begin
  rec.Name := StringOfChar(Char(65 + Random(26)), 3);
  rec.Age := Random(150);
  Queue.Enqueue(rec);
  Text := Format('当前队列成员总数: %d', [Queue.Count]);

  {让 Memo1 配合显示}
  Memo1.Lines.Add(Format('%s, %d', [rec.Name, rec.Age]));
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  rec: TRec;
begin
  if Queue.Count = 0 then Exit;
  rec := Queue.Dequeue;
  ShowMessage(Format('%s, %d', [rec.Name, rec.Age]));
  Text := Format('当前队列成员总数: %d', [Queue.Count]);

  {让 Memo1 配合显示}
  Memo1.Lines.Delete(0);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  rec: TRec;
begin
  if Queue.Count = 0 then Exit;
  rec := Queue.Peek;
  ShowMessage(Format('%s, %d', [rec.Name, rec.Age]));
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Queue:= Tqueue<TRec>.Create();

  Memo1.Clear;
  Button1.Caption := Button1.Caption + ' 入列';
  Button2.Caption := Button2.Caption + ' 出列';
  Button3.Caption := Button3.Caption + ' 下一个出列的...';
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Queue.Free;
end;

泛型类TStack

堆栈类与队列类相似,堆栈的出列采用的是先进后出的方式
压栈采用Stack.Push(rec); 出栈采用Stack.Pop;下一个出列的依然是用Stack.Peek;

泛型类TDictionary<cardinal, string>;

类似字典,一个值对应着一个值,可以是数字与字符串,也可以是字符串与字符串.
在字典场景下使用该泛型极为方便.

uses
  System.Generics.Collections;

var
  Dictionary: TDictionary<cardinal, string>;
procedure TForm1.Button1Click(Sender: TObject);
var
  key: Cardinal;
  value: string;
  str: string;
  k,v: Boolean;
begin
  key := StrToIntDef(Edit1.Text, 0);
  value := Edit2.Text;
  if value = '' then value := 'Null';

  k := Dictionary.ContainsKey(key);     {Key 是否存在}
  v := Dictionary.ContainsValue(value); {Value 是否存在}

  if not k then
  begin
    Dictionary.Add(key, value);
    Memo1.Lines.Add(Format('%d=%s', [key, value])); {同步显示}
  end;

  if k and not v then
  begin
    str := Format('key 已存在: %d=%s; 是否修改其值?', [key, Dictionary[key]]);
    if MessageBox(0, PChar(str), '提示', MB_OKCANCEL or MB_ICONQUESTION) = mrOk then
    begin
      //Dictionary[key] := value; {Dictionary[key] = Dictionary.Item[key]}
      Dictionary.AddOrSetValue(key, value);       {也可使用上一句}
      Memo1.Lines.Values[IntToStr(key)] := value; {同步显示}
    end;
  end;

  if k and v then
  begin
    str := Format('%d=%s 已存在, 不能重复添加', [key, value]);
    MessageBox(0, PChar(str), '错误', MB_OK + MB_ICONHAND);
  end;

  Text := IntToStr(Dictionary.Count);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  key: Integer;
  i: Integer;
begin
  key := StrToIntDef(Edit1.Text, 0);

  if not Dictionary.ContainsKey(key) then
  begin
    ShowMessageFmt('key: %d 不存在', [key]);
    Exit;
  end;

  Dictionary.Remove(key);
  Text := IntToStr(Dictionary.Count);

  {同步显示}
  i := Memo1.Lines.IndexOfName(IntToStr(key));
  if i > -1 then Memo1.Lines.Delete(i);
end;

procedure TForm1.Button3Click(Sender: TObject);
var
  key: Integer;
  value: string;
begin
  key := StrToIntDef(Edit1.Text, 0);
  if Dictionary.TryGetValue(key, value) then
    ShowMessageFmt('key: %d 已存在, 其值是: %s', [key, value])
  else
    ShowMessageFmt('key: %d 不存在', [key])
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
  Dictionary.Clear;
  Text := IntToStr(Dictionary.Count);
  Memo1.Clear; {同步显示}
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  Dictionary:=TDictionary<cardinal, string>.Create;
  Memo1.Clear;
  Button1.Caption := Button1.Caption + ' 添加';
  Button2.Caption := Button2.Caption + ' 删除';
  Button3.Caption := Button3.Caption + ' 尝试取值';
  Button4.Caption := Button4.Caption + ' 清空';

  Edit1.Clear;
  Edit2.Clear;
  Edit1.NumbersOnly := True;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Dictionary.Free;
end;

标签:begin,end,Delphi,Arr,TObject,TForm1,语法,Caption,泛型
来源: https://www.cnblogs.com/YXGust/p/16647561.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有