Но это было бы sloooow! намного медленнее, чем массивы.
TSome = record
next :PList;
...
function GetNext(skip: cardinal): TSome;
property ArrayLike[index: cardinal]: TSome read GetNext; default;
end;
....
{$T+}
function TSome.GetNext(skip: cardinal): TSome;
type PSome = PList;
var candidate: PSome;
begin
candidate := @Self;
while skip > 0 do
candidate := candidate.Next;
if candidate = nil then raise EBoundsError.Create('out of index');
Dec(skip);
end;
Result := candidate^;
end;
...
var x: TSome;
x[0] = x.ArrayLike[0] = x;
ВНИМАНИЕ: поскольку вы работаете с записями, а не с классами - вы получаете КОПИЮ записи не самой записи;
Как в var x,y: TSome; y := x;
- вы делаете новую копию данных, а не второй указатель на те же данные.
Это, а также сама проблема структуры списка сделает этот вид доступа медленнее, гораздо медленнее, чем массив.
И
var x,y,z: TSome; i: integer;
x.SomeValue := 1;
y.SomeValue := 2;
x.Next := @y;
i := x[1].SomeValue;
// i == 2 (making copy of y, then taking a SomeValue from it)
x[1].SomeValue := 10;
z := x[1];
z.SomeValue := 20;
i := x[1].SomeValue;
// still i == 2 - we were NOT changing the value in y itself, we were making DATA COPIES of y and changing COPIES
именно второй объект нужен – vpe27339
@fantaghirocco: Я хотел бы использовать 'while' цикл вместо' repeat' цикла, например: 'индекс: = 2; tmp: = list; в то время как (tmp <> nil) и (index> 0) начинаются tmp: = tmp^.next; Декабрь (индекс); end; 'Подумайте, что произойдет, если вызывающий хочет узел с индексом 0; Ваш цикл 'repeat' завершится неудачно. –
@ vpe27339: вы хотите * второй узел в списке *, или * узел в индексе 2 *? Это разные узлы. Индексы начинаются с 0, поэтому первым узлом является индекс 0, второй - индекс 1, третий - индекс 2 и т. Д. –