内联函数无法访问非公共API:@PublishedApi vs @Suppress vs @JvmSynthetic

hot*_*key 18 inline public kotlin java-synthetic-methods

在Kotlin中,当我有一个非公共成员并且inline fun调用它时,有一个编译错误说:

错误:(22,25)Kotlin:Public-API内联函数无法访问中private fun f(): Unit定义的非公共APIcom.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功能吗?在某些情况下,最终的程序会失败吗?我尝试使用这个技巧从内联函数调用非内联函数,并且它有效,但它看起来很可疑.

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

    将第二个解决方案与字节码中的合成标志组合在一起.我不确定这是否正确用法@JvmSynthetic,但这似乎隐藏了Java代码的功能,这解决了问题@PublishedApi internal.

那么,哪种解决方案是从公共内联系统中调用非公共功能的最佳方式?我没有看到每个解决方案的缺点是什么?

Ily*_*lya 21

@PublishedApi internal 是暴露非公共API以在公共内联函数中使用的预期方式.

@PublishedApi internal成员变得有效公开,其名称不会被破坏(如果您注意到相反的情况,请提交错误).

@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")是缺乏@PublisedApi基于抑制错误的创可贴的解决方法因此不推荐.随着@PublishedApi这种抑制的引入将从stdlib中清除.

@JvmSynthetic结合使用@PublishedApi是一种有趣的方法,但是在调试时可能会出现一些问题,但我不确定.

  • 谢谢你的回答.是的,现在我看到`@PublishedApi internal`留下了完整的名字,我错了.顺便说一句,IDE应该隐藏"@PublishedApi内部"成员完成或阻止他们的使用吗?并且,出于好奇,`@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")`出了什么问题? (4认同)
  • @StevenJeuris,我什么也没遇到,尽管我不能说我经常使用这种组合。好吧,我的旨在发现故障的实验都没有发现任何结果。 (2认同)