Модераторы: Poseidon, Snowy, bems, MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Использование анонимных процедур (D2010) 
:(
    Опции темы
VLK32
Дата 22.1.2011, 22:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 22.1.2011

Репутация: нет
Всего: нет



Есть описание ссылки на функцию:

Код

TSelector<T> = reference to function (const Item:T; const Index:Integer=-1):Boolean;


Есть функция кот. возвращает ссылку на анонимную функцию с уже конкретизированным типом, например:

Код

 function GetCurrentSelector:TSelector<TTestRec>;
  var op,e12,e13 : Integer;
      substr     : String;
  begin
   //
   op  := MainForm.ComboBox1.ItemIndex;
   e12 := StrToInt(MainForm.Edit12.Text);
   e13 := StrToInt(MainForm.Edit13.Text);
   substr := MainForm.Edit13.Text;
   if MainForm.RadioButton3.Checked then Exit(
    function (const Item:TTestRec; const Index:Integer=-1):Boolean
     begin
      if op=0 then Result := Item.ID<e12
              else Result := Item.ID>e12;
     end);
   //
   if MainForm.RadioButton4.Checked then Exit(
    function (const Item:TTestRec; const Index:Integer=-1):Boolean
     begin
      Result := (Item.ID mod e13)=0;
     end);
   //
   if MainForm.RadioButton5.Checked then Exit(
    function (const Item:TTestRec; const Index:Integer=-1):Boolean
      begin
       Result := Pos(substr,Item.Data)<>0;
      end);
  end;


И в результате:

Код

 procedure TMainForm.BTN_SELECT1Click(Sender:TObject);
  var selector : TSelector<TTestRec>;
  begin

   // такое присваивание работает
   selector := function (const Item:TTestRec; const Index:Integer=-1):Boolean
     begin
      Result := Item.ID>15;
     end;
   
   // а вот такое присваивание не работает!
   selector := GetCurrentSelector;

   Memo2.Clear;
   A1.SelectAsObject(selector).Perform
    (procedure (var Item:TTestRec; const Index:Integer=-1)
               begin
                Memo2.Lines.Add(Format('%7d: %7d %s',[Index,Item.ID,Item.Data]));
               end);

  end;


Компилятор выдает ошибку: Incompatible types: 'TSelector<Main.TTestRec>' and 'Procedure'

Вопрос. Что я делаю не так?
PM MAIL   Вверх
VLK32
Дата 23.1.2011, 02:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 22.1.2011

Репутация: нет
Всего: нет



Спасибо за помощь, все свободны smile

Пишу для тех кто может напороться на эти грабли.

Вот это работает:

Код

 type TFunc2<T> = reference to function(const A,B:T):Integer;

 function MakeAdder():TFunc2<Integer>;
  begin
   Exit(
   function (const x,y: Integer):Integer
    begin
      Result := x + y;
    end);
  end;

 procedure WTF;
  var Adder : TFunc2<Integer>;

  begin
   Adder := MakeAdder();
   WriteLn(Adder(22,66));
   Readln;
  end;


А вот это не работает:

Код

 type TFunc2<T> = reference to function(const A,B:T):Integer;

 function MakeAdder:TFunc2<Integer>;
  begin
   Exit(
   function (const x,y: Integer):Integer
    begin
      Result := x + y;
    end);
  end;

 procedure WTF;
  var Adder : TFunc2<Integer>;

  begin
   Adder := MakeAdder;
   WriteLn(Adder(22,66));
   Readln;
  end;


Есть знатоки, которые смогут мне объяснить чем одно принципиально отличается от другого?
PM MAIL   Вверх
skyboy
Дата 23.1.2011, 02:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 4
Всего: 260



предупреждаю, что в последний раз работал ажно с Delphi 7, где не было никаких анонимных функций. а вот процедурный тип переменных уже был.
замечу, что 
Цитата(VLK32 @  23.1.2011,  01:00 Найти цитируемый пост)
Adder := MakeAdder();

выполнит функцию MakeAdder, которая вернет в качестве результата процедуру. Эта процедура запишется в переменную и позже выполнится с двумя аргументами.
Во втором случае
Цитата(VLK32 @  23.1.2011,  01:00 Найти цитируемый пост)
Adder := MakeAdder;

в переменную Adder ты пытаешься закинуть не анонимную процедуру, которую вернет MakeAdder, а саму MakeAdder. Что не позволительно, так как MakeAdder не совпадает с описанием типа TFunc2<integer>. А даже если бы и совпадало, то ты при вызове 
Код

MakeAdder(22, 66);

ты бы выполнил саму MakeAdder, а не анонимную функцию, описанную в ней.
PM MAIL   Вверх
VLK32
Дата 23.1.2011, 02:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 7
Регистрация: 22.1.2011

Репутация: нет
Всего: нет



Вот голова моя садовая! Ты прав. Снимаю вопрос.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0818 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.