- Код: Выделить всё
unit Unit1;
{$mode objfpc}{$H+}
{$MODESWITCH ADVANCEDRECORDS}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs;
type
TForm1 = class(TForm)
private
{ private declarations }
public
{ public declarations }
end;
var
Form1: TForm1;
type
LstGrandTyp = ^PLstGrandTyp;
PLstGrandTyp = packed record
early, Next: LstGrandTyp;
end;
LstTyp01 = ^PLstTyp01;
PLstTyp01 = packed record
early, Next: LstTyp01;
Value: byte;
end;
LstTyp02 = ^PLstTyp02;
PLstTyp02 = packed record
early, Next: LstTyp02;
Value: string[255];
end;
implementation
type
generic LstEnumerator<LstTyp> = record//LstTyp можно обозвать и просто T, главное, что бы уникально
private
lst, lst_save: LstTyp;
public
constructor Create(const Value: LstTyp);
function GetEnumerator: LstEnumerator;
function MoveNext: boolean;
property Current: LstTyp read lst;
end;
constructor LstEnumerator.Create(const Value: LstTyp);
begin
lst := Value;
lst_save := nil;
end;
function LstEnumerator.GetEnumerator: LstEnumerator;
begin
Result := Self;
end;
function LstEnumerator.MoveNext: boolean;
begin
if lst <> nil then
begin
//...какой-то код
LstGrandTyp(lst) := LstGrandTyp(lst)^.next;//Здесь обрезка типа, причём если тип задан не в interface, а в implementation, то не компилируется. Но это внутренняя операция, на внешний тип она не влияет.
Result := True;
end else Result := False;
end;
1. Почему нельзя использовать вот так:
- Код: Выделить всё
var
i01, lst01: LstTyp01;
i02, lst02: LstTyp02;
begin
for i01 in LstEnumerator<LstTyp01>.Create(lst01) do
begin
i01^.Value := 10;
end;
for i02 in LstEnumerator<LstTyp02>.Create(lst02) do
begin
i02^.Value := 'ten';
end;
end.
2. Почему вот на это выдаёт ошибку:
- Код: Выделить всё
var
i01, lst01: LstTyp01;
i02, lst02: LstTyp02;
begin
for i01 in LstEnumerator.Create(lst01) do
begin
i01^.Value := 10;
end;
end.
Компиляция проекта, цель: C:\Users\Admin\AppData\Local\Temp\project1.exe: Код завершения 1, ошибок: 1, предупреждений: 1
unit1.pas(83,40) Warning: Variable "lst01" does not seem to be initialized
unit1.pas(83,7) Error: Internal error 200304241
3. Почему при использовании таким образом:
- Код: Выделить всё
var
i01, lst01: LstTyp01;
i02, lst02: LstTyp02;
en01: specialize LstEnumerator<LstTyp01>;
en02: specialize LstEnumerator<LstTyp02>;
begin
for i01 in en01.Create(lst01) do
begin
i01^.Value := 10;
end;
for i02 in en02.Create(lst02) do
begin
i02^.Value := 'ten';
end;
end.
не дают обратиься к:
- Код: Выделить всё
lst^.next