E2555 Невозможно захватить символ «Я» - PullRequest
0 голосов
/ 11 января 2019

Когда я запускаю следующий код, я получаю E2555 Cannot capture symbol 'Self'.

type
  TLookupTable = record
    FData: TArray<TOtherRec>;
    procedure ReverseLeftToRight;
  end;

procedure TLookupTable.ReverseLeftToRight;
begin
  Parallel.For(0, Length(FData)-1).NoWait.Execute(procedure(i: integer) begin
    FData[i]:= FData[i].ReverseLeftRight;
  end); {for i}
end;

Как мне это исправить?

1 Ответ

0 голосов
/ 11 января 2019

Проблема в том, что var параметры (включая скрытые параметры var для Self) не фиксируются. Однако мы не хотим копировать записи, что было бы бесполезно, потому что тогда наш метод не будет работать.

Хитрость, чтобы сделать скрытый параметр self явным.
Если это класс, тогда легко (var S:= Self), если нет, вам придется объявить указатель на вашу запись.

procedure TLookupTable.ReverseLeftToRight;
type 
  PLookupTable = ^TLookupTable;
var
  S: PLookupTable;
begin
  S:= @Self;
  Parallel.For(0, Length(FData)-1).NoWait.Execute(procedure(i: integer) begin
    S.FData[i]:= S.FData[i].ReverseLeftRight;
  end); {for i}
end;

Теперь компилятор больше не жалуется.
(Обратите внимание, что я использую неявный синтаксис для S^.xyz).

Дельфи Рио
Использование встроенного объявления var, как показано ниже, не работает.

  //S: PLookupTable;
begin
  var S:= @Self; //inline declaration
  Parallel.For(0, Length(FData)-1).NoWait.Execute(procedure(i: integer) begin
    S.FData[i]:= S.FData[i].ReverseLeftRight;
  end); {for i}

Создает: E2018 Record, object or class type required.
Я предполагаю, что встроенный @Self разрешается в общий указатель, что является позором, потому что есть достаточно информации, чтобы вывести правильный тип для встроенной переменной.

Асинхронные проблемы
Если вы выполняете код, используя поток / задачу Async (.NoWait), то может быть лучше поместить FData в локальную переменную. FData, будучи динамическим массивом, уже является указателем (поэтому копирование не будет, только подсчет ссылок). А динамические массивы не имеют семантики копирования при записи, поэтому оригинал будет обновляться.
Таким образом, запись Self может выйти из области видимости во время выполнения кода, что приведет к нарушению доступа (или хуже).

...