内联函数无法访问非公开API:@PublishedApi vs @Suppress vs @JvmSynthetic
在Kotlin,当我有一个非公众成员和一个inline fun
时候,有一个编译错误说:
错误:(22,25)Kotlin:公共API内联函数无法访问非公共API
private fun f(): Unit
在com.example
定义的private fun f(): Unit
我发现有几种方法可以在公共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
的问题。
那么,哪种解决方案是从公共内联中调用非公共function的最佳方式呢? 每个解决方案的缺点是什么,我没有看到?
@PublishedApi internal
是暴露非公开API用于公共内联函数的预期方式。
这个@PublishedApi internal
成员变得有效的公开,它的名字不会被破坏(如果你注意到相反的话,请提交一个bug)。
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
是一个基于抑制错误的缺乏@PublisedApi
的创可贴解决方法,因此不推荐使用。 随着@PublishedApi
的引入,这个抑制将被从stdlib中清除。
@JvmSynthetic
结合@PublishedApi
是一个有趣的方法,但是它可以导致调试时出现一些问题,虽然我不确定。