37

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

Error:(22, 25) Kotlin: Public-API inline function cannot access non-public-API private fun f(): Unitdefined incom.example

我找到了几种在 public 中调用我的函数的方法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@PublishedApi internal.

那么,这些解决方案中的哪一个是从公共内联函数调用非公共函数的最佳方式?我看不到的每种解决方案的缺点是什么?

4

1 回答 1

38

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

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

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

@JvmSynthetic结合@PublishedApi是一种有趣的方法,但是它在调试时可能会导致一些问题,尽管我不确定。

于 2017-01-28T03:00:26.860 回答