Intereting Posts
Проблема с компиляцией Dagger2 в Котлине Момент не может быть сериализован в соответствующий формат даже с помощью jackson-datatype-jsr310 проверка отражения kotlin с нулевыми типами Kotlin: Как наследовать свойство в классе данных Ленивая инициализация элемента с нулевым значением null в listOf (), а не null в listOf (значение) в Kotlin в одном лайнере? Как преобразовать кодировку win1251 в UTF8 внутри Kotlin? Как я могу запускать заливки Kotlin-Script (* .kts) из Gradle? Спецификация Jpa, чтобы найти подмножество значения поля Преобразование наблюдаемого в текущее с противодавлением в RxJava2 Поле редактирования мягкой клавиатуры Android Текст ярлыка не обновляется, хотя поток пользовательского интерфейса кажется отзывчивым Android – Сделать функцию ложной / не запускать подавить предупреждение неиспользуемой переменной Нужно ли знать kotlin, чтобы получить сертификацию AAD (Associate Android Developer)?

Когда лямбда-параметры должны быть noinline в Котлин?

Я часто сталкиваюсь с ошибками в замкнутых функциях Котлина, где параметры лямбда должны быть отмечены noinline . В других случаях параметры лямбда, похоже, работают нормально. Я прочитал документацию Котлина о встроенных функциях , и, похоже, это оперативный проход, объясняющий правило:

Inlinable lambdas может быть вызван только внутри встроенных функций или передан как встроенные аргументы, но noinline можно манипулировать любым способом, который нам нравится: хранится в полях, передается и т. Д.

У меня возникли проблемы с распаковкой этих концепций. В частности, я не уверен, что полностью понимаю то, что я не могу сделать (включая все, что есть в «и т. Д.») С помощью встроенной лямбды – другими словами, вещи, которые лишат его возможности быть вложенными. Есть ли хорошая ссылка или более подробное объяснение / примеры использования, которые дисквалифицируют параметр лямбда Котлина, из-за того, что они встроены?

Это меньше «дисквалификации» лямбды от того, чтобы быть встроенным, и больше «это действие не может быть выполнено на вложенной лямбда».

Я как-то ответил на это здесь .

Вложенные методы непосредственно вставляются в сайт вызова, как и любые встроенные lambdas.

Чтобы повторно использовать старый пример,

это примерно в main здесь:

 fun withLambda(lambda: () -> Unit) { lambda() } inline fun inlinedLambda(lambda: () -> Unit) { lambda() } fun main(args: Array<String>) { withLambda { println("Hello, world") } inlinedLambda { println("Hello, world") } } 

преобразуется в это:

 fun main(args: Array<String>) { withLambda { println("Hello, world") } println("Hello, world") // <- Directly inserted! } 

То, что вы не можете сделать с вложенной лямбдой, – это рассматривать его как объект .

Это означает, что вы не можете сохранить его в поле:

 val a = lambda // <-- error 

или методы вызова на нем:

 lambda.toString() // <-- error 

потому что это не объект.

Он также не может быть передан в качестве аргумента другой функции

 func(lambda) // <-- error 

если лямбда не обозначена как crossinline , а параметр другой функции является inline .

Это в основном указано в документации.

noinline можно манипулировать любым способом, который нам нравится: хранится в полях, проходит вокруг и т. д.

Обратите внимание, что некоторые встроенные функции могут вызывать lambdas, переданные им как параметры … Чтобы указать, что параметр лямбда должен быть отмечен модификатором кросс-линии:

Подумайте о встроенных lambdas как о том, что их код был непосредственно вставлен в этот метод. Концептуально они фактически не существуют, и «вызов» их просто вставляет их содержимое в вызывающий метод.