powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Захват переменной в анонимной процедуре
25 сообщений из 30, страница 1 из 2
Захват переменной в анонимной процедуре
    #39823216
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Коллеги, как вернуть значение переменной.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
procedure CallActionFrm(var id: Integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
begin
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          id := 100;
        end;
      end
      );
  end;
end;



Ошибка - E2555 Cannot capture symbol 'id'

Как обойти?
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823245
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Присвоить ее локальной. Захватить локальную. Потом по выходу локальную опять присвоить в var параметр.
var и иногда const не захватываются.
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823251
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite, делаю, не получается:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
begin
  tmp := I;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          tmp := 100;
        end;
      end
      );
    I := tmp;
  end;
end;

...

procedure TfrmAdmPlanItem.btnSearchClick(Sender: TObject);
var
  id: Integer;
begin
  id := 1;
  CallActionFrm2(id);
  edtInn.Text := IntToStr(id); // получаю id = 1, а не 100!
end;
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823269
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А вы сделайте
Код: pascal
1.
2.
3.
4.
if AResult = mrOk then
  tmp := 100
else
  tmp := 200;


Вангую что вернется 200
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823303
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteА вы сделайте
Код: pascal
1.
2.
3.
4.
if AResult = mrOk then
  tmp := 100
else
  tmp := 200;


Вангую что вернется 200

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
begin
  tmp := I;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          tmp := 100;
        end
        else
          tmp := 200;
      end
      );
    I := tmp;
  end;
end;

...

procedure TfrmAdmPlanItem.btnSearchClick(Sender: TObject);
var
  id: Integer;
begin
  id := 1;
  CallActionFrm2(id);
  edtInn.Text := IntToStr(id); // Возвращает 1!
end;
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823307
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wsnet,

А так не сработает?
Код: pascal
1.
PInteger(@id)^ := 100;
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823372
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexeywsnet,

А так не сработает?
Код: pascal
1.
PInteger(@id)^ := 100;



Тоже самое

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
  PInteger: ^Integer;
begin
  PInteger := @I;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          PInteger^ := 100; //id = 1!
          ShowMessage('test');
        end
        else
          PInteger^ := 200;
      end
      );
  end;
end;
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823388
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wsnet,

А отладчик на строке "I := tmp;" какое значение tmp показывает?
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823393
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В 10.2 вот этот код работает корректно:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
type
  TPR = reference to procedure;

procedure Test2(PR: TPR);
begin
  PR();
end;

procedure Test(var Id: Integer);
var
  Idd: Integer;
begin
  Idd := Id;
  Test2(procedure
    begin
      Idd := 200;
    end);
  Id := Idd;
end;

var
  Id: Integer;
begin
  try
    Id := 1;
    WriteLn(Id);
    Test(Id);
    WriteLn(Id);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.


А у вас?
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823464
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А анонимная функция вызывается? Вангую, что нет.
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823475
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteА анонимная функция вызывается? Вангую, что нет.

Да она отрабатывает как нужно.
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823506
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вызов ShowModal синхронный или асинхронный?
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823535
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite, пробую и синхронно и асинхронно все тоже.

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
  PInteger: ^Integer;
begin
  PInteger := @I;
  UniSession.Synchronize;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          PInteger^ := 100;
          ShowMessage('test'); //Отрабатывает! Но переменная - не  захватывается. 
        end
        else
          PInteger^ := 200;
      end
      );
  end;
end;
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823542
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если я пробую вызвать через метод объекта, указав тип процедуры - как метод объекта, все работает, но так бы не хотелось - ибо хочу обработку переменной Id иметь в одной процедуре в зависимости от mrOk или mrCancel:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
type
TCallBack = procedure(Sender: TComponent; Res: Integer) of object;

procedure CallActionFrm(var Id: Integer; pCallBack: TCallBack = nil);
var
  vMsg: TfrmBaseDictionaryList;
begin
  vMsg := TfrmBaseDictionaryList.Create(UniApplication);
  if Assigned(pCallBack) then
  begin
    vMsg.ShowModal(pCallBack);
    Id := 200;// ура переменная захватывается!
  end;
end;

procedure TfrmAdmPlanItem.btnSearchClick(Sender: TObject);
var id:Integer;
begin
id = 100;
CallActionFrm( id, DoCallBack);
end;
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823554
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpВ 10.2 вот этот код работает корректно:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
type
  TPR = reference to procedure;

procedure Test2(PR: TPR);
begin
  PR();
end;

procedure Test(var Id: Integer);
var
  Idd: Integer;
begin
  Idd := Id;
  Test2(procedure
    begin
      Idd := 200;
    end);
  Id := Idd;
end;

var
  Id: Integer;
begin
  try
    Id := 1;
    WriteLn(Id);
    Test(Id);
    WriteLn(Id);
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  ReadLn;
end.


А у вас?

Этот код работает! Но в чем принципиальное отличие от моего метода - там переменная не захватывается!
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823599
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
wsnet, Анонимная функция - это интерфейс. В интерфейсе есть переменная, которая отвечает за это. Погляди в отладчике, присваивается ли ей значение.
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823604
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
  PInteger: ^Integer;
begin
  PInteger := @I;
  UniSession.Synchronize;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          PInteger^ := 100;
          ShowMessage('test');
        end
        else
          PInteger^ := 200;
      end
      );
  end;
  ShowMessage('Exit');
end;

В каком порядке появятся сообщения?
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823699
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
_Vasilisk_
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
procedure CallActionFrm2(var I: integer);
var
  AfrmBaseDictionaryList: TfrmBaseDictionaryList;
  tmp: Integer;
  PInteger: ^Integer;
begin
  PInteger := @I;
  UniSession.Synchronize;
  with TfrmBaseDictionaryList.Create(UniApplication) do
  begin
    ShowModal(
      procedure(Sender: TComponent; AResult: Integer)
      begin
        if AResult = mrOk then
        begin
          PInteger^ := 100;
          ShowMessage('test');
        end
        else
          PInteger^ := 200;
      end
      );
  end;
  ShowMessage('Exit');
end;

В каком порядке появятся сообщения?

Странно, но сначала 'Exit', а только потом 'test'. Отчего так?
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823700
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
UniApplication

У вас случаем не UniGui приложение?
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823701
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823702
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite, да UniGui.
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823703
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ShowModal doesn't block execution in UniGUI, use callbacks to execute your code after the form is closed
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823706
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вызов то асинхронный. Конечно работать не будет... Локальные замыкания работают только при синхронном вызове анонимки.
Ваша строка кода
I := tmp;
Выполнится раньше чем вызовется анонимка.
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823711
Фотография wsnet
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteВызов то асинхронный. Конечно работать не будет... Локальные замыкания работают только при синхронном вызове анонимки.
Ваша строка кода
I := tmp;
Выполнится раньше чем вызовется анонимка.

Теперь ясно! Только в Callback буду получать значение теперь! Спасибо!
...
Рейтинг: 0 / 0
Захват переменной в анонимной процедуре
    #39823712
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite Локальные замыкания работают только при синхронном вызове анонимки
Я тут соврал..будут работать и при асинхронном..
Ведь внутри анонимки контекст уже захвачен...
А вот код после ShowModal у unigui выполнится раньше чем анонимка, это надо понимать...
...
Рейтинг: 0 / 0
25 сообщений из 30, страница 1 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Захват переменной в анонимной процедуре
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]