Я считаю, что этот вопрос требует очень субъективного суждения.Я разработчик Delphi старой школы и склонен с вами согласиться.Замыкания не только увеличивают определенные риски (как указывает Дэвид Х в комментариях), они также снижают читабельность для всех классически обученных разработчиков Delphi.Так почему они вообще были добавлены в язык?Например, в Delphi XE функция форматирования синтаксиса и замыкания не работали вместе, и это увеличило мое недоверие к замыканиям;Сколько вещей добавлено в компилятор Delphi, что IDE не была полностью обновлена для поддержки?Вы знаете, что вы недовольный старый таймер, когда публично признаете, что были бы счастливы, если бы язык Delphi был заморожен на уровне Delphi 7 и никогда больше не улучшался.Но Delphi - это живой, мощный, развивающийся синтаксис.И это хорошо.Повторите это для себя, когда вы обнаружите, что старая рукоятка начинает действовать.Попробуйте.
Я могу вспомнить как минимум десять мест, где методы Anonymous действительно имеют смысл, и, следовательно, причины, по которым вы должны их использовать, несмотря на мой предыдущий комментарий, что я им не доверяю.Я укажу только те два, которые я решил использовать лично, и ограничения, которые я налагаю на себя, когда использую их:
Сортировка методов в классах контейнеров в Generics.Collectionsпримите анонимный метод, чтобы вы могли легко обеспечить логику сортировки без необходимости писать обычную (неанонимную) функцию, которая совпадает с той же сигнатурой, что и метод сортировки.Новый синтаксис дженериков идет рука об руку с этим стилем, и хотя он поначалу кажется вам чуждым, он растет для вас и становится, если не совсем удачным, по крайней мере более удобным, чем альтернативы.
Методы TThread, такие как Synchronize, перегружены, и помимо поддержки одного TThreadMethod в качестве параметра Thread.Synchronize(aClassMethodWithoutParameters)
, мне всегда было больно получать параметры в этот метод синхронизации.теперь вы можете использовать замыкание (анонимный метод) и передавать параметры в.
Пределы, которые я рекомендую при написании анонимных методов:
A.У меня есть личное эмпирическое правило, состоящее только из ОДНОГО замыкания для каждой функции, и всякий раз, когда их больше одного, рефакторинг этого бита кода для его собственного метода.Это удерживает цикломатическую сложность ваших «методов» от сумасшествия.
B.Кроме того, внутри каждого замыкания я предпочитаю иметь только один вызов метода и его параметры, и если в итоге я пишу гигантские блоки кода, я переписываю их как методы.Замыкания для захвата переменных, а не карт-бланш для написания бесконечно скрученного спагетти-кода.
Пример сортировки:
var
aContainer:TList<TPair<String, Integer>>;
begin
aContainer.Sort(
TMyComparer.Construct(
function (const L, R: TPair<String, Integer>): integer
begin
result := SysUtils.CompareStr(L.Key,R.Key);
end ) {Construct end} ); {aContainer.Sort end}
end;
Обновление: один комментарий указывает на «языковое уродство», я полагаючто увеличение относится к разнице между необходимостью писать:
x.Sort(
TMyComparer.Construct(
function (const L, R: TPair<String, Integer>): integer
begin
result := SysUtils.CompareStr(L.Key,R.Key);
end ) );
Вместо следующего гипотетического синтаксиса с типом утки (или я бы сказал, выведенные типы), который я только что изобрел здесь для сравнения:
x.Sort( lambda( [L,R], [ SysUtils.CompareStr(L.Key,R.Key) ] ) )
Некоторые другие языки, такие как Smalltalk и Python, могут писать лямбды более компактно, потому что они динамически типизированы.Например, потребность в IComparer в качестве типа, передаваемого методу Sort () в контейнере, является примером сложности, вызванной интерфейсом, которому должны следовать строго типизированные языки с обобщениями для реализации таких черт, как упорядочение.Требуется для сортировки.Я не думаю, что был хороший способ сделать это.Лично я ненавижу видеть процедуру, начинайте и заканчивайте ключевые слова в круглых скобках вызова функций, но я не вижу, что еще можно было бы разумно сделать.