Ключевое слово Котлина

Я прочитал этот вопрос, но у меня есть более фундаментальный вопрос относительно crossinline слова crossinline . Я не совсем уверен, какая проблема решает и как это решает.

Из документов Котлина ,

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

[Акцент добавлен]

Это утверждение неоднозначно для меня. Во-первых, у меня возникают проблемы с изображением того, что подразумевается под «такими случаями». Я имею общее представление о том, что проблема, но не может придумать хороший пример этого.

Во-вторых, фраза «Чтобы указать это», можно читать несколькими способами. Чтобы указать, что? Что конкретный случай не допускается? Что это разрешено? Этот нелокальный поток управления в определенном определении функции разрешен (или нет)?

Короче говоря, мне трудно понять, каков контекст для использования этого на самом деле, что его использует для общения с клиентами и каковы ожидаемые результаты применения этого ключевого слова.

Во-первых, у меня возникают проблемы с изображением того, что подразумевается под «такими случаями». Я имею общее представление о том, что проблема, но не может придумать хороший пример этого.

Вот пример:

 interface SomeInterface { fun someFunction(): Unit } inline fun someInterfaceBy(f: () -> Unit): SomeInterface { return object : SomeInterface { override fun someFunction() = f() // ^^^ // Error: Can't inline 'f' here: it may contain non-local returns. // Add 'crossinline' modifier to parameter declaration 'f'. } } 

Здесь функция, которая передается someInterfaceBy { ... } , встроена в анонимный класс, реализующий SomeInterface . Компиляция каждого сайта- someInterfaceBy создает новый класс с другой реализацией someFunction() .

Чтобы узнать, что может пойти не так, рассмотрите вызов someInterfaceBy { ... } :

 fun foo() { val i = someInterfaceBy { return } // do something with `i` } 

Внутри встроенной лямбда return нелокально и на самом деле означает возврат из foo . Но поскольку лямбда не вызывается и не течет в объект i , возврат из foo может быть абсолютно бессмысленным: что, если i.someFunction() (и, следовательно, лямбда) вызывается после того, как foo уже вернулся или даже в другом потоке?

В общем случае «такие случаи» означают inline функции, которые вызывают их функциональные параметры не в их собственных телах (эффективно, то есть принимая во внимание другие встроенные функции), но внутри некоторых других функций, которые они объявляют, например, в не-встроенных lambdas и анонимных объектах.


Во-вторых, фраза «Чтобы указать это», можно читать несколькими способами. Чтобы указать, что? Что конкретный случай не допускается? Что это разрешено? Этот нелокальный поток управления в определенном определении функции разрешен (или нет)?

Именно так проблема, описанная выше, исправлена ​​в дизайне языка Котлин: всякий раз, когда inline функция намеревается встроить свой функциональный параметр где-нибудь, где он не может быть вызван на месте, но сохранен и вызывается позже, параметр inline функции должен быть отмечен как crossinline , что указывает на то, что нелокальный поток управления не разрешен в проходящих здесь лямбдах.

  • Отладчик Android Studio не работает при использовании поддержки на C ++
  • Kotlin: Сохранить изображение в базе данных
  • Программно сделать изображениеView видимым / невидимым с помощью переменной
  • Невозможно вызвать функцию из блока init из-за свойства val
  • Объявление пользовательской «чистой» задачи при использовании стандартных плагинов жизненного цикла Gradle запрещено
  • compileReleaseKotlin не работает с java.lang.ClassNotFoundException: com.sun.tools.javac.util.Context
  • Возврат определенных экземпляров из общей функции
  • Настройка Kotlin при выражении
  • @StringRes, @DrawableRes, @LayoutRes и т. Д. Андроидные аннотации lint check с параметрами kotlin
  • Обратные вызовы Android и повторное использование кода
  • Утверждение с сообщением об ошибке в Котине
  • Interesting Posts

    как использовать DecoratingStringHashMapper с kotlin?

    Как реализовать формулу Стирлинга с BigDecimal и BigInteger в Котлине?

    Как использовать @DbEnumValue с Ebean в Котлине?

    «Java» «не распознается как внутренняя или внешняя команда, программный или командный файл. в Котлине

    @Parcelize аннотации toghether с наследованием

    Как позволить классу данных реализовать интерфейс / расширяет свойства суперкласса в Котлине?

    Параметр функции Kotlin: Val не может быть переназначен

    Android с изменением даты и времени, но снова надавить, Firebase просто возвращает истекший токен

    Получите enum constant, используя его значение

    Поддерживает ли Котлин монадическое понимание?

    Как настроить версию кода байта Kotlin в проекте Gradle на Java 8?

    Написание javascript-приложений с Kotlin

    почему kotlin использует === сравнить примитивный тип, равный друг другу, если они имеют одинаковое значение

    gradle multi-project: каталог сборки появляется в корневом каталоге, содержащем артефакты Котлина

    Файл открытого актива Android Kotlin

    Давайте будем гением компьютера.