Здравствуйте, Qbit86, Вы писали:
Q>Локальные функции — это вопрос скоупа. Просто найди все обычные рекомендации из C++/C# о том, что надо объявляеть локальные переменные ближе к их использованию, и зачем ограничивать их области видимости. А потом примени эти рекомендации к локальным функциям.
Дело в том, что у меня есть опыт использования чего-то похожего на практике. Причём в случае, где без делегатов/локальных функций особо не обойтись. Штука с кучей магии под капотом, что-то типа динамически генерируемого КА с автоматическим разруливанием циклов/зависимостей. Казалось бы, идеальный пример для local functions.
Аля
void Handle(Something y)
{
Rule(x => x.Sum > 100, x => { x.Sum = 100; });
IfChanged(x => x.Sum, x => { x.WorkLimit = WorkFromScale(x.Sum); });
IfChanged(x => x.WorkLimit, x => FixWorked(x));
IfChanged(x => x.Worked, x => FixSum(x));
Run(y);
}
Так вот, несмотря на то, что в принципе все эти WorkFromScale(), FixWorked(), FixSum() etc состояли из одной-двух строчек, на практике никто и никогда добровольно не записывал их прямо по месту использования. Хотя хелпер для этого был предусмотрен.
Потому что с точки зрения логики конкретное действие и настройка workflow — это принципиально разные вещи. И нефиг их смешивать в один метод.
Q>Выносить локальные функции в скоуп класса так же неприятно, как выносить локальные переменные алгоритма в поля класса.
Не, фигня получается. В результате в одном методе смешиваются две ответственности: реализация и собственно логика в виде наборов вызовов этой самой реализации. Ещё и с кучей неявных зависимостей из-за замыканий.
Ну, т.е. мы вернулись к ситуации, от которой пытались уйти рефакторингом на отдельные методы
Q>В VSCode аналогичная фича тоже приятно реализована.
+1.