powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Анонимные методы. Какие дают преимущества?
63 сообщений из 63, показаны все 3 страниц
Анонимные методы. Какие дают преимущества?
    #39801179
Artem.1st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уважаемые, delphi-гуру

Кто-нибудь использует Анонимные методы ?
Поделитесь опытом, какие у них преимущества в сравнении с процедурными типами?

Вот, например: Анонимные методы можно объявлять, прямо в месте использования. Но, неужели кто-то этим пользуется?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
function MakeAdder(y: Integer): TFuncOfInt;
begin
  Result := {start anonymous method} function(x: Integer) : Integer
  begin
    Result := x + y;
  end; {end anonymous method}
end;


А какую еще выгоду дают Анонимные методы ?

Спасибо.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801180
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Простой пример:
Код: pascal
1.
2.
3.
4.
List.Sort(function (A, B: TMyRec): boolean
          begin
            Result:=A.Name>B.Name;
          end)



Это проще и наглядней чем городить отдельную фунцию для сортировки в другом месте кода.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801234
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Еще пример - можно с минимальными усилиями выполнять асинхронные задачи:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
    
  TThread.CreateAnonymousThread(
    procedure
    begin
      SendSms(ARecipient, AMessage);
    end
    ).Start;
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801238
Artem.1st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
>> Это проще и наглядней

rgreat, asutp2,
спасибо, что откликнулись.

Про наглядность ..., любой дотошный читатель :-) обратит внимание, что Ваши примеры(как и примеры в официальном Help) выглядят наглядно, если это функция из одной короткой строки .

Ну, хорошо.
А какую еще выгоду дают Анонимные методы, в сравнении с процедурными типами?
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801246
Artem.1st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Классический вариант такой:

Код: pascal
1.
2.
3.
4.
5.
   function  MySortFunc
   procedure MySmsProc;
   ...
   List.Sort(MySortFunc);
   TThread.CreateAnonymousThread(MySmsProc).Start;



А так стало наглядней ?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
  List.Sort(function (A, B: TMyRec): boolean
          begin
            Result:=A.Name>B.Name;
          end)

  TThread.CreateAnonymousThread(
    procedure
    begin
      SendSms(ARecipient, AMessage);
    end
    ).Start;



rgreat, asutp2, заранее извините,
я специально чучь-чуть "провоцирую", но честно хочу осознать эту "наглядность"
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801250
Beltar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Судя по инфе от сотрудников самой Аброкадабры, практически не используются. Причина очевидна, выглядят они хорошо только для предельно короткого кода. Дополняется наличием вложенных функций, позволяющих внятно оформить код тут же рядом.

А если люди что-то используют очень редко, то они будут забывать о самой наличии возможности, даже если иногда она работает. Так-то ведь даже у Label есть одно применение, где оно радикально уменьшает число строк кода, - мгновенный выход из вложенных циклов. Но я не думаю, что люди помнят об этом.

Среди меня, например, практически не получила распространения конструкция for each, хотя при использовании с датасетами она исключает частую ошибку с забыванием Next.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801253
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st,

обрати внимание - в моем случае используется вызов метода SendSms. Он больше, чем одна строчка кода :-)
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801255
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st,

у себя постоянно распараллеливание вычислений:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
 Parallel.ForI(TempLow, TempHigh,
  procedure (i1, i2, tdi: integer)
  var
   i: integer;
  begin
   for i := i1 to i2 do
    EnsureSliceOpened(i, True);
  end,
  pfInterleaved);


Так же удобно использовать при обустройстве слоёв приложения. Когда нужно развязать какие-то модули между собой. Пример кину.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801261
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1stПро наглядность ...
Pascal-style и наглядность не совместимы.. Вот если бы они ввели маркер => как это делается в других языках..
Код: pascal
1.
List.Sort(a, b => Result := a.Name>b.Name)



Код: pascal
1.
List.Sort(a, b: Int32 => Result := a.Name > b.Name)



Код: pascal
1.
TThread.CreateAnonymousThread( () => SendSms(ARecipient, AMessage)).Start;
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801264
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Пример. Заполнение списка в гуе из библиотеки. Библиотека не должна ничего знать про верхние слои (например - гуй) но должна быть способна с ними работать.

Часть кода библиотеки:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
procedure FillTransferSytax(OnTransferSyntaxFound: TNotifyStrReferProc);
var
 i: integer;
begin
 for i := 0 to DICOMDictonary.NUMBER_OF_DCMUIDS - 1 do
  if DICOMDictonary.DCMUIDDictonary[i].UIDType = utTRANSFERSYNTAX then
   OnTransferSyntaxFound(DICOMDictonary.DCMUIDDictonary[i].UIDName);
end;

Гуй:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
procedure TSaveAsOptionsForm.FormCreate(Sender: TObject);
begin
 FillTransferSytax(procedure (const s: string)
  begin
   SpTBXComboBox1.AddItem(s, nil);
  end);
end;

Анонимный тип:
Код: pascal
1.
TNotifyStrReferProc    = reference to procedure (const s: string);
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801267
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite,

и что здесь что? я до сих пор в этих птичьих знаках без понятия :)
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801274
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite,

"()" это процедура или функция? она может что-то вернуть? судя по плюсам это скорее функция. как такую функцию(процедуру?) описать и передать куда-то? ну это первое, что вот сразу вижу.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801279
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st,

Поиск при помощи анонимной функции:

Само тело поиска:

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
function TDICOMParserMainForm.DoSearch(Comparer: TSearchTree): boolean;
begin
 ...
 ...
 ...
 ...
 ...
  while Assigned(TempNode) do
  begin
   if (TObject(TempNode.Data) is TDICOMElement) and Comparer(TempNode) then
    Break;
   TempNode := TempNode.GetNext;
  end;
 ...
 ...
 ...
end;



Дальше, в зависимости от надобности, вызываем поиск с разными компараторами:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
type
 TSearchTree = reference to function (TreeNode: TTreeNode): boolean;

var
 Comparer: TSearchTree;

 Comparer :=
  function (TreeNode: TTreeNode): boolean
  begin
   Result := Pos(AnsiUpperCase(FSearchStr), AnsiUpperCase(TreeNode.Text)) <> 0;
  end;

 if not DoSearch(Comparer) then
  ShowNotFound(FSearchStr);
 ...
  Comparer :=
   function (TreeNode: TTreeNode): boolean
   begin
    Result := TreeNode.Data = NodeData;
   end;

  DoSearch(Comparer);

Можно без дополнительных ссылок, можно как у меня.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801281
Beltar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В чем выразилась анонимность типа TNotifyStrReferProc?

Это просто расширенный функционал процедурных типов, когда вызываемый метод лениво нормально описывать.

И да, выглядит омерзительно.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801285
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1stА какую еще выгоду дают Анонимные методы ?
Самое главное - это захват контекста (читай про замыкания). Можно местное почитать отсюда 17814553 , и дальше, сколько осилишь :)
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801293
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Beltar,

не там смотришь. анонимность не в TNotifyStrReferProc, а в переданной ему функции. выглядит отлично, использовать очень удобно. контекст захватывается, модули развязаны.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801299
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Онанимные методы на самом деле процедуры...
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801303
RWolf
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анонимные процедуры хорошо ложатся на паттерны Strategy/Visitor. Выгода здесь в том, что они избавляют от необходимости делать новый класс, придумывать ему имя, создавать экземпляр этого класса, следить за его временем жизни.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801310
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К слову - кому интересны паттерны в Delphi, можно глянуть свежую книгу Primož Gabrijelčič'а "Hands-On Design Patterns with Delphi" Build applications using idiomatic, extensible, and concurrent design patterns in Delphi. Ищите в интернетах, либо заходите в телеграмм-канал, там можно скачать.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801313
Artem.1st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonArtem.1st,
у себя постоянно (1) распараллеливание вычислений:
Так же удобно использовать при (2) обустройстве слоёв приложения. Когда нужно (3) развязать какие-то модули между собой.
makhaon , спасибо что ответили.
см. 1, 2, 3, Вы пишите о серьезных прикладных задачах. Это то, что меня интересует.
Вопрос: Зачем в серьезных задачах, Вы пользуетесь не обычным Процедурным типом, а новым Анонимным методом?

Вот обычный вариант. Процедурный Тип:
Код: pascal
1.
2.
3.
4.
5.
6.
procedure MyProc(i1, i2, tdi: integer);
begin
   ....
end,

Parallel.ForI(TempLow, TempHigh, MyProc, pfInterleaved);



Вот новый вариант. Анонимный Метод. Это стало "наглядней" ?
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
 Parallel.ForI(TempLow, TempHigh,
  procedure (i1, i2, tdi: integer)
  var
   i: integer;
  begin
   for i := i1 to i2 do
    EnsureSliceOpened(i, True);
  end,
  pfInterleaved);



Я искренне подозреваю, что у Анонимных Методов должно быть еще другое преимущество , т.к. их "наглядность" очень сомнительна...

Так что это?
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801315
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st,

преимущество сказали: захват контекста.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801317
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st,

авторВот обычный вариант. Процедурный Тип:

в обычном варианте нет доступа к экземпляру класса, это только локальная процедура. в анонимном же варианте (как у меня все) есть доступ к экземпляру класса (к селфу), откуда идёт вызов:
EnsureSliceOpened - это метод класса, а не просто какая-то локальная процедура
SpTBXComboBox1.AddItem - это метод конкретного комбобокса, который в данный момент заполняем.
В компораторах доступны FSearchStr и NodeData, к которым в случае вызова обычной процедуры было бы сложнее достучаться.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801323
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: pascal
1.
2.
3.
4.
5.
6.
7.
        Take(C).Plugin<TAQPControlAnimations>
          .BackgroundColorAnimation(clRed, 700, 76, TAQ.Ease(etCubic, emInOut))
          .Each(function(AQ: TAQ; O: TObject): Boolean
            begin
              TWinControl(C).SetFocus;
              Result := False
            end);
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801327
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Citeмаркер => как это делается в других языкахне во всех других такой маркер используется
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801330
Artem.1st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyСамое главное - это захват контекста (читай про замыкания)
Большое спасибо за ссылку.
Буду изучать.

Пока плохо ориентируюсь в терминах: "Захват контекста" - это отдать область видимости наружу?
Если "Да" , то опять же обычный Процедурный Тип может быть вложенным(т.е. процедура внутри процедуры).
А значит "Захват контекста" можно делать и без Анонимных методов, при помощи обычного вложенного Процедурного Типа.
Так? Нет?
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801331
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1stу Анонимных Методов должно быть еще другое преимущество в некоторых оптимизирующих компайлерах их применение позволяет иногда сгенерить код оптимальнее
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801340
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1stКлассический вариант такой:

Код: pascal
1.
2.
3.
4.
5.
   function  MySortFunc
   procedure MySmsProc;
   ...
   List.Sort(MySortFunc);
   TThread.CreateAnonymousThread(MySmsProc).Start;



А так стало наглядней ?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
  List.Sort(function (A, B: TMyRec): boolean
          begin
            Result:=A.Name>B.Name;
          end)

  TThread.CreateAnonymousThread(
    procedure
    begin
      SendSms(ARecipient, AMessage);
    end
    ).Start;



rgreat, asutp2, заранее извините,
я специально чучь-чуть "провоцирую", но честно хочу осознать эту "наглядность"Так - не стало. Но ты забыл реализацию неанонимных функций в код добавить.

Если добавишь и правильно отформатируешь - наглядней будет именно анонимно.
Ибо код функции сортировки будет лежать сразу перед взглядом а не где-то еще.

Но это работает на коротких функциях и процедрурах. Более десятка строк это будет выглядеть слишком тяжеловесно.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801371
Artem.1st
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CitePascal-style и наглядность
X-Cite, спасибо, что участвуете в теме.
Я помню, Вы хорошо разбираетесь в C++.

Скажите, в C++ есть возможность описать функцию в любом месте кода, например, внутри цикла “for” ?
Вот, в Delphi это стало возможно. Я искренне пытаюсь осознать какие дает преимущества ... :-/
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801373
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st,
В си++ даже лямды появились :) Стандарт расширяется :)
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801388
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1stX-CitePascal-style и наглядность
X-Cite, спасибо, что участвуете в теме.
Я помню, Вы хорошо разбираетесь в C++.

Скажите, в C++ есть возможность описать функцию в любом месте кода, например, внутри цикла “for” ?
Вот, в Delphi это стало возможно. Я искренне пытаюсь осознать какие дает преимущества ... :-/
Вы меня с кем-то путаете... Я не разбираюсь в С++

Чтобы понять как работают замыкания и почему анонимные функции как нельзя лучше подходят для "Функций высшего порядка"
https://habr.com/ru/post/244945

Например каррирование или мемоизация - очень мощные штуки, но к сожалению в delphi не работающие нормально... Я уже в QC запостил пару багов с захватом контекста..

Захват контекста нужен, чтобы в другие классы не передавать параметры, которые там не должны жить, т.к. каждый класс должен выполнять ровно одну задачу.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801391
ёёёёё
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st...в C++ есть возможность описать функцию в любом месте кода, например, внутри цикла “for” ?
...
Конечно, есть.
Более того, в состав стандартной библиотеки включили специальные формы, основанные на лямбдах:

https://ru.cppreference.com/w/cpp/algorithm/for_each

Лябды в с++ в миллион раз мощнее того, что имеем в дельфи.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801392
ziv-2014
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема реализации анонимных функций в Delphi заключается в том, что они реализованы через интерфейсы и не совместимы с реализацией в других языках.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801458
Foxpc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ziv-2014,

за это бы им следовала оторвать в руки, и всунуть их на место (в задний проход) . В c# к примеру анонимные функции легко запоминают переданные в них локальные значения, и при вызове сразу нескольких функций, с разными переменными будут давать разный результат, который был передан

А в Delphi что????? Смех один.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
using System;

class MainClass {
  delegate void Test(string funcName);
  delegate void Test2();

  static Test2 CallTest(string Name, Test callback)
  {
    return () => { callback(Name); };  
  }

  public static void Main (string[] args) {
    Test2 a = CallTest("Call1",
     (string funcName) => { Console.WriteLine (funcName);   });
    Test2 a2 = CallTest("Call2",
     (string funcName) => { Console.WriteLine (funcName);   });

    a2();
    a();
  }
}

...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801475
Foxpc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот так более эстетичнее
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
using System;

class MainClass {
  delegate void Test(string funcName);
  delegate void Test2();

  static Test2 CallTest(string Name, Test callback)
  {
    return () => { callback(Name); };  
  }

  public static void Main (string[] args) {
    Test HTest = (string funcName) => { Console.WriteLine (funcName);   };

    Test2 a = CallTest("Call1", HTest);
    Test2 a2 = CallTest("Call2", HTest);

    a2();
    a();
  }
}

...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801485
Maxim.K
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Artem.1st "Захват контекста" - это отдать область видимости наружу?
Если "Да" , то опять же обычный Процедурный Тип может быть вложенным(т.е. процедура внутри процедуры).
А значит "Захват контекста" можно делать и без Анонимных методов, при помощи обычного вложенного Процедурного Типа.
Так? Нет?
Нет.
Процедурный Тип в Delphi применим только для автономных процедур(не для вложенных). Т.е. вложенные процедуры(компилятор называет “локальными”) не являются Процедурным Типом, и их нельзя использовать в качестве переменных или параметров.

А вот новые Анонимные методы - это вариант вложенных процедур, которые совместимы с Процедурным Типом, и их можно присваивать и передать наружу(с Захваченным контекстом).
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801502
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Foxpcziv-2014,

за это бы им следовала оторвать в руки, и всунуть их на место (в задний проход) . В c# к примеру анонимные функции легко запоминают переданные в них локальные значения, и при вызове сразу нескольких функций, с разными переменными будут давать разный результат, который был передан

А в Delphi что????? Смех один.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
using System;

class MainClass {
  delegate void Test(string funcName);
  delegate void Test2();

  static Test2 CallTest(string Name, Test callback)
  {
    return () => { callback(Name); };  
  }

  public static void Main (string[] args) {
    Test2 a = CallTest("Call1",
     (string funcName) => { Console.WriteLine (funcName);   });
    Test2 a2 = CallTest("Call2",
     (string funcName) => { Console.WriteLine (funcName);   });

    a2();
    a();
  }
}

Ммм, это делфи? по мне, так это c++ билдер
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801506
Michael Longneck
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Массово использую анонимные методы. Например для исключения while not DS.Eof do DS.Next; End; и вообще практически везде, где требуются процедурные типы
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801507
asutp2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ааа, поторопился) конечно же, это не с++ билдер) но и не делфи.

Foxpc , приведи пример на делфи, который будет работать некорректно
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801516
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
asutp2ааа, поторопился) конечно же, это не с++ билдер) но и не делфи.

Foxpc , приведи пример на делфи, который будет работать некорректно

Это применимо к асинхронному выполнению, когда к примеру захват контекста в одной нити, а выполнение в другой.
Сравните ниже.

Код: 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.
35.
36.
37.
38.
39.
40.
41.
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Classes,
  System.Threading;

begin
  var Lock := TObject.Create();
  for var i := 1 to 10 do
    TTask.Run(
      procedure
      begin
        TMonitor.Enter(Lock);
        Writeln('i = ', i);
        TMonitor.Exit(Lock);
      end
    );

//  Sleep(2000);

  var p := procedure(k: Int32)
           begin
            TTask.Run(
              procedure
              begin
                TMonitor.Enter(Lock);
                Writeln('k = ', k);
                TMonitor.Exit(Lock);
              end
            );
           end;

  for var i := 1 to 10 do
    p(i);
  Readln;
end.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801550
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хотя в C# тоже самое...
Захват контекста из другой нити работает также
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
        static void Test(int i)
        {
            Task.Run(() => System.Console.WriteLine(i));
        }

        static void Main(string[] args)
        {
            for (int i = 1; i <= 10; i++)
            {
                Task.Run(() => System.Console.WriteLine(i)); // Будет как в Delphi 11 11 11 11 ....
            }
            for (int i = 1; i <= 10; i++)
            {
                Test(i);                
            }
            System.Console.ReadKey();
        }
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801559
Фотография wadman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteЗахват контекста из другой нити работает также
А ява тут сругается, что переменная должна быть финализированной.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801712
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Artem.1st,

авторА значит "Захват контекста" можно делать и без Анонимных методов, при помощи обычного вложенного Процедурного Типа. Так? Нет?

Я не знаю что ты называешь процедурным типом.
Но вот так сделать нельзя::

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
procedure TSomeClass.OtherMethod;

  procedure Test;
  begin
   Self.SomeMethod; //это метод класса TSomeClass
  end;

begin
  TParallel.For(Test);
end;



Компилятор выдаст ошибку (собственно - из-за отсутствия возможности захватить контекст). И вот что бы это стало возможным как раз анонимные функции и нужны.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801734
Фотография _Vasilisk_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Использую редко. Но очень классно их использовать для всяких callback

Код: 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.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
  TChartSupport = class
  strict private
    type
      TInitSeriesProc<T: TChartSeries> = reference to procedure(ASeries: T);
      TOnMarkerStatus = procedure(const AXMarker, AYMarker: string) of object;
  strict protected
    function AddSeries<T: TChartSeries>(const AName: string;
      const AInit: TInitSeriesProc<T> = nil): T;
  end;

function TChartSupport.AddSeries<T>(const AName: string;
  const AInit: TInitSeriesProc<T>): T;
begin
    Result := FindSrsByTitle<T>(AName);
    if Result = nil then begin
      Result := T(TChartSeriesClass(T).Create(MainChart));
      Result.Active := False;
      Result.ParentChart := MainChart;
      Result.Title := AName;
      Result.ShowInLegend := False;
      Result.XValues.Order := loNone;
      Result.YValues.Order := loNone;
      if Assigned(AInit) then
        AInit(Result);
    end;
  end;
end;

  FMarkerX := AddSeries<TChartShape>(CMarkerXTitle, procedure (ASeries: TChartShape)
    begin
      ASeries.Pen.Width := CLineWidth;
      ASeries.Style := chasVertLine;
      ASeries.BeforeDrawValues := MarkerXBeforeDrawValues;
    end
  );

    Result := AddSeries<TAreaSeries>(LTitle, procedure(ASeries: TAreaSeries)
      begin
        ASeries.Tag := CDataSeries;
        ASeries.AreaLinesPen.Visible := False;
        ASeries.LinePen.Width := 7;
        ASeries.LinePen.Visible := False;
        ASeries.Stairs := True;
        ASeries.ShowInLegend := True;
      end
    );

...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801763
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Метод как метод только без имени. Но если часто использовать паттерны Visitor, Dependency Injection, Control Inversion и тд, то:
* меньше писать кода;
* код не размазан по юниту а в месте его использования.
PS: Все можно и на ASM написать :)
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801764
Фотография Dmitry Arefiev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кто-то выше сказал, что Эмба не использует анонимные методы. Все с точностью наоборот ...
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801797
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В Java Script без анонимных/стрелочных функций сейчас как без рук. Все фреймворки под них заточены. Смотрятся они в JS очень красиво (изящнее и читабельнее, чем в лямбды C# из-за динамической типизации).
Зато в JS нет классов (есть только эмуляция за счёт сахара) и такой классной штуки как "function of object" (TMethod) в JS нету, что ведёт в постоянным извращениям типа bind.
Я к тому, что в Delphi анонимные функции нужны куда реже, чем в других языках. Имхо, и слава богу.
Такое ощущение, что некоторые, особенно молодые C# - программисты, начинают забывать (или не знают), как объявить поле класса без лямбд или как сделать обычный метод. Везде лямбды лепят. Это хорошо видно из статей на Хабре, посвящённых C#. В C# сделать анонимный метод с нормальным описанием параметров куда сложнее, чем вставить лямбду. Ведь там нет ключевого слово function / func / fn и т.п., поэтому приходится городить огород.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801873
Beltar
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Эмба у себя использует, они-то свой продукт лучше всех знают. Потом их спецы едут в народ, опрашивают его, узнают, что народ не очень понимает, зачем это всё надо, и очень расстраиваются. Ну кому понравится, когда старались, работали, а результат не ценят.

авторПроцедурный Тип в Delphi применим только для автономных процедур(не для вложенных). Т.е. вложенные процедуры(компилятор называет “локальными”) не являются Процедурным Типом, и их нельзя использовать в качестве переменных или параметров.

Дык вот это само по себе странность. Причем странность неочевидная, если про нее не знать, как та же невозможность передать property в var параметр. И вообще непонятная. Если можно прямо в центре процедурки зафигачить другую процедурку, которая будет иметь точку входа и при этом еще и захватывать контекст, то что мешает сделать то же самое для вложенных функций, которые с точки зрения их пользователя есть то же самое, только записанное чуть в стороне?
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801876
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Beltar,

Совместимость с легаси
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801887
white_nigger
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мы тоже у себя всё чаще используем. Ибо иногда удобнее
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801921
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite,

С одной стороны бесспорно то, что Делфи всегда был хорош обратной совместимостью. И до 90% кода еще первых версий соберется либо сразу (если изначально был хорошо написан - то скорее всего и соберется) либо с минимальными правками. Для долгоиграющих проектов отличный язык.
Для сравнения путь Гугл: постоянно ломается совместимость, а потом программеры плачут:
https://habr.com/ru/post/446346/
С другой, я сам слабо понимаю, какая совместимость может сломаться если локальные процедуры будет разрешено передавать как процедурный тип (если, конечно, подходят параметры). Или почему запрещено передавать проперти как переменные. Особенно те, которые без сеттеров.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801926
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonИли почему запрещено передавать проперти как переменные. Особенно те, которые без сеттеров.
Потому что свойство это абстракция. Сегодня у тебя сеттера нет, а завтра он есть.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801947
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

отлично. Будет сеттер - будет ошибка. Нет сеттера - нет ошибки. Известно, что без сеттера проперти трактуется как обычная переменная без какой-либо дополнительной обвязки.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801951
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да и сеттер могли бы обвязать, что уж... Чай не бином Ньютона.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801959
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
makhaonИзвестно, что без сеттера проперти трактуется как обычная переменная без какой-либо дополнительной обвязки.
Известно, что свойство это абстракция усиливающая инкапсуляцию (сокрытие деталей реализации). Декларируя свойство, программист говорит компилятору, что это не переменная, не поле, а именно способ доступа к некотором данным.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801965
x1ca4064
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
BeltarавторПроцедурный Тип в Delphi применим только для автономных процедур(не для вложенных). Т.е. вложенные процедуры(компилятор называет “локальными”) не являются Процедурным Типом, и их нельзя использовать в качестве переменных или параметров.

Дык вот это само по себе странность. Причем странность неочевидная, если про нее не знать, как та же невозможность передать property в var параметр. И вообще непонятная. Если можно прямо в центре процедурки зафигачить другую процедурку, которая будет иметь точку входа и при этом еще и захватывать контекст, то что мешает сделать то же самое для вложенных функций, которые с точки зрения их пользователя есть то же самое, только записанное чуть в стороне?
Это странность тогда, когда рассматривают язык только с точки зрения синтаксиса, а не реализации, что часто очень удобно: представляшь, какой код должен получиться после компиляции, а из этого уже создаешь синтаксическую конструкцию, которая к этому приводит. Var и property - это синтаксический "сахар", без которого можно обойтись ( var - очень древний "сахар", property - чуть новее), поэтому если представить, что var - это просто адрес переменной, а property это вызов соотвествующих гетеров и сетеров, становится понятно, почему property нельзя передать как var параметр. С локальными процедурами аналогично - локальная процедура отличается от "независимой" процедуры именно указателем на контескт "родителя", она видима, только пока контекст родителя доступен, поэтому ее нельзя вернуть "наружу". Как реализованны анонимные процедуры с захватом контекста, я не изучал (пока) и с трудом представляю, т.к. (обычно) локальные переменные - это просто кусок стека, который при завершении процедуры освободится, а значит контекст должен быть где-то в другом месте, что должно приводить ко всяким проблемам со времени жизни этого контекста и пр. Написанное относится к обычным компилируемым реализациям, в которых нет RTTI: информация об именах переменных и функций не попадает в результирующий код, однако необходимость удобной сериализации привела к некоторому сближению компилируемых и интерпретируемых концепций - появились published свойства и RTTI, соответсвенно. Дальше - больше, подозреваю, скоро появится еще и функция eval(SourceCode:string):TVariant, которая в runtime выполняет код :)
Сумбурно как-то получилось.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801971
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSerВ Java Script без анонимных/стрелочных функций сейчас как без рук. Все фреймворки под них заточены. Смотрятся они в JS очень красиво (изящнее и читабельнее, чем в лямбды C# из-за динамической типизации).
Оффтоп, правда, но я вот никак не оценю плюшки стрелочных. На какой-то элементарщине в один оператор из примеров да, они дают большое сокращение. Но потом в реальном коде добавляется еще один оператор, а значит, и скобки, потом еще один, вынуждая делать тело функции многострочным, а потом вдруг и this понадобится... в итоге все сокращение выливается лишь в => вместо function. Учитывая лучшую воспринимаемость слова и автогенерацию кода средой, преимущество так себе.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801981
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Захват контекста + ручная реализация анонимки 21836708
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39801986
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

если соблюдать принципы инкапсуляции, то я не могу создать переменную в public вообще. нет выбора: переменная или свойство, вот в чем проблема. да, можно нарушить инкапсуляционные принципы и вытянуть часть переменных наружу. но как-то так себе идея. ну да ладно. обсуждаем не это :)
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39802049
DmSer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Василий 2DmSerВ Java Script без анонимных/стрелочных функций сейчас как без рук. Все фреймворки под них заточены. Смотрятся они в JS очень красиво (изящнее и читабельнее, чем в лямбды C# из-за динамической типизации).
Оффтоп, правда, но я вот никак не оценю плюшки стрелочных. На какой-то элементарщине в один оператор из примеров да, они дают большое сокращение. Но потом в реальном коде добавляется еще один оператор, а значит, и скобки, потом еще один, вынуждая делать тело функции многострочным, а потом вдруг и this понадобится... в итоге все сокращение выливается лишь в => вместо function. Учитывая лучшую воспринимаемость слова и автогенерацию кода средой, преимущество так себе.

Посмотрите учебный курс ReactJS. Там стрелочные функции очень активно используются и очень наглядно смотрятся. Там, где строк много, можно объявить таким образом:
const MyFunc = function(a,b) {
......
}

либо так:
const MyFunc = (a, b) => ({})

Не обязательно стрелочную функцию объявлять по месту использования, можно раньше.
Если сравнивать с C# (сужу по статьям на том же Хабре), то там лямбды объявляются в основном (или всегда?) именно по месту использования (а раньше видимо и не получится, т.к. нужно заранее знать какие типы).
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39802099
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну к примеру самый яркий пример псевдокода (через стрелочные, чтобы нагляднее было)
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
  var Item := 'Товар1';
  var Context := GetContext(blabla);
  var PriceStorage := TTask.Future<TPrice>( () => Result := Context.GetPriceStorage(Item));
  var PriceCache := TTask.Future<TPrice>( () => Result := Context.GetPriceCache(Item));
  var PriceApi := TTask.Future<TPrice>( () => Result := Context.GetPriceApi(Item));
  тут еще куча кода на получение нужных объектов и кое-какая логика. Пока она работает мы получаем из разных источников цены.
  var Prices := TPrices.Agregate([PriceStorage.Value, PriceCache.Value, PriceApi.Value]);
  Context.Send(Prices);
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39802108
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проблема того же TTask в том, что там Run принимает процедурный тип без аргументов
т.е. если есть какой-то метод без параметров, который хотим вызвать асинхронно - проблем нет
Если метод с параметрами, то уже его указать нельзя, т.к.
TTask.Run ожидает TProc
Приходится писать что-то вроде
Код: pascal
1.
2.
3.
4.
5.
6.
TTask.Run(
  procedure
  begin
    MyProc(Item);
  end
);


Как бы без анонимного метода не обойтись, т.к. сам класс ни про какой Item может не знать, если Item как входной параметр в текущем методе
Но, если к примеру применить карирование, то получим вполне красивый код
Код: pascal
1.
TTask.Run(Curry<string>(MyProc)(Item)());


Но к сожалению карирование на дженериках - работает не верно, контекст параметров захватывается некорректно. (Уже в QC)
А писать карирующую функцию под каждый метод со своими параметрами - нет смысла, проще анонимками разрулить.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39802178
Василий 2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmSerПосмотрите учебный курс ReactJS. Там стрелочные функции очень активно используются и очень наглядно смотрятся. Там, где строк много, можно объявить таким образом:
const MyFunc = function(a,b) {
......
}

либо так:
const MyFunc = (a, b) => ({})

Посмотрел. О чем я и говорил - на мелкоте - дает выигрыш в краткости. И это не полноценный код, а обвязка интерфейса. А вот когда начинается что-то посерьезнее
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    const moves = history.map((step, move) => {
      const desc = move ?
        'Go to move #' + move :
        'Go to game start';
      return (
        <li>
          <button onClick={() => this.jumpTo(move)}>{desc}</button>
        </li>
      );
    });


особой разницы с
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    const moves = history.map(function(step, move) {
      const desc = move ?
        'Go to move #' + move :
        'Go to game start';
      return (
        <li>
          <button onClick={() => this.jumpTo(move)}>{desc}</button>
        </li>
      );
    });


нету. Второй вариант даже выигрывает в наглядности, т.к. слово function подсвечивается.
В Delphi за счет куда большей многословности краткая форма могла бы выиграть существенней, но едва ли на это пойдут - это не в стиле языка.
...
Рейтинг: 0 / 0
Анонимные методы. Какие дают преимущества?
    #39810171
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Даже в php пошли на сахар в виде стрелочных функций...
Было
Код: php
1.
2.
3.
$result = array_filter($paths,  function ($v) use ($names) {
    return in_array($v, $names);
});


Стало
Код: php
1.
$result = array_filter($paths,  fn($v) => in_array($v, $names));
...
Рейтинг: 0 / 0
63 сообщений из 63, показаны все 3 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Анонимные методы. Какие дают преимущества?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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