Можно ли пометить лямбду как inline в Kotlin
Что проверяют
Понимаете ли вы, что inline относится к функции, а не к значению, и знаете ли настоящую причину, по которой этот модификатор существует. Экономия на объекте лямбды тут далеко не главное.
Как отвечать
Саму лямбду пометить нельзя, модификатор ставится на функцию, которая её принимает. Когда функция помечена как встраиваемая, её тело и все переданные лямбды подставляются в место вызова, и объект функции не создаётся вовсе.
Управлять этим можно двумя модификаторами уже у параметра:
noinlineзапрещает подстановку конкретной лямбды, нужен когда её надо сохранить в поле или передать дальше как значение;crossinlineподстановку разрешает, но запрещает нелокальный возврат, нужен когда лямбда вызывается не напрямую, а из другого объекта или потока.
inline fun <reified T> List<*>.firstOf(
predicate: (T) -> Boolean
): T? = filterIsInstance<T>().firstOrNull(predicate)Главных причин делать функцию встраиваемой две: овеществлённый параметр типа, как в примере выше, где тип доступен в рантайме, и возможность написать return внутри лямбды так, чтобы он вышел из внешней функции. Ради одной экономии на объекте это не делают.
Где спотыкаются
Ставят модификатор на функцию без параметров-функций. Компилятор выдаёт предупреждение о бесполезности: выигрыша нет, а байткод дублируется в каждой точке вызова.
Второе: встраивают большие функции, вызываемые из десятков мест. В Android это прямой рост размера сборки и числа методов, а стектрейсы становятся заметно менее читаемыми, потому что отдельного кадра вызова уже нет.
Третье: путают два модификатора у параметра. Пока лямбда встраивается, return внутри неё выходит из внешней функции, и это сюрприз для тех, кто ждал выхода только из лямбды. Стоит запретить нелокальный возврат или сохранить лямбду в переменную, и тот же код молча меняет смысл.