Встроенная функция не может получить доступ к непубличным API: @PublishedApi vs @Suppress vs @JvmSynthetic

В Kotlin, когда у меня есть непубличный член и inline fun которое его вызывает, возникает ошибка компиляции:

Ошибка: (22, 25). Kotlin: встроенная функция Public-API не может получить доступ к private fun f(): Unit не относящимся к публичному API. private fun f(): Unit определенная в com.example

Я нашел несколько способов назвать свою функцию внутри общедоступного inline fun , но что это лучший способ сделать это?

Предположим, что у меня есть private fun f() { } . Тогда параметры, которые я нашел, следующие:

  • fun f() { }

    Просто сделайте это общедоступным. Это базовое решение, но, если у остальных окажутся серьезные недостатки, это может оказаться лучшим.

  • @PublishedApi internal fun f() { }

    Представленный в Kotlin 1.1-M04 , аннотация может быть применена к внутреннему члену, что делает его эффективно публичным. Следствие, которое я заметил, это то, что любой пользователь библиотеки все равно сможет вызвать его из кода Java, вот что мне не нравится в этом.

  • @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") inline fun g() { f() }

    Найденный в источниках stdlib , эта аннотация, кажется, подавляет ошибку при применении к вызывающей функции. Но каковы его ограничения? Может ли он использоваться только для inline функций? Повреждает ли программа в некоторых случаях? Я попытался вызвать функцию non-inline из встроенного с этим трюком, и это сработало, но выглядит подозрительно.

  • @JvmSynthetic @PublishedApi internal fun f() { }

    Объедините второе решение с синтетическим флагом в байтекоде. Я не уверен, что это правильное использование @JvmSynthetic , но это, похоже, скрывает эту функцию от кода Java, что решает проблему @PublishedApi internal .

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

@PublishedApi internal – это предполагаемый способ публикации непубличного API для использования в публичных встроенных функциях.

Этот @PublishedApi internal член @PublishedApi internal становится общедоступным, и его имя не искажается (если вы заметили обратное, напишите ошибку).

@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") является обходной способ обхода в отсутствие @PublisedApi основанный на подавлении ошибки и поэтому не рекомендуется. С введением @PublishedApi это подавление будет очищено от stdlib.

@JvmSynthetic сочетании с @PublishedApi – интересный подход, однако он может вызвать некоторые проблемы при отладке, хотя я не уверен.

Intereting Posts
Какой законный способ получить аннотации к чистому качеству Котлина через отражение, они всегда отсутствуют? Android Things: NullPointerException при получении данных через USB UART по малине PI 3 Как назначить одно и то же имя переменной класса в kotlin? Заявление о создании платформы с сопоставимым maven-source-plugin не работает для kotlin Invoke RxJava2 отменяемый / одноразовый из правильной нити Kotlin возвращает тот же объект из метода Factory Не удалось построить Gradle с помощью Kotlin, Scala и Java Конструктор супертипов объекта Котлин не может компилировать приложение tornadofx в автономную банку Firebase & Retrieving Elements Ошибка: ошибка: разрешены только безопасные (?.) Или непустые (!!.) Вызовы в приемнике с нулевым значением типа View? Dagger2 и квалификаторы в зависимых компонентах Большой размер файла при преобразовании растрового изображения в PDF android TabLayout установить значок с сервера