内联函数无法访问非公共 API:@PublishedApi vs @Suppress vs @JvmSynthetic [英] Inline function cannot access non-public-API: @PublishedApi vs @Suppress vs @JvmSynthetic

查看:19
本文介绍了内联函数无法访问非公共 API:@PublishedApi vs @Suppress vs @JvmSynthetic的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

In Kotlin, when I have a non-public member and an inline fun that calls it, there's a compilation error saying:

Error:(22, 25) Kotlin: Public-API inline function cannot access non-public-API private fun f(): Unitcom.example 中定义

Error:(22, 25) Kotlin: Public-API inline function cannot access non-public-API private fun f(): Unit defined in com.example

我找到了几种在公共 inline fun 中调用我的函数的方法,但哪种方法最好?

I found several ways to call my function inside a public inline fun, but which is the best way to do it?

假设我有一个 private fun f() { }.然后我找到的选项是:

Suppose I have a private fun f() { }. Then the options I found are:

  • 有趣的 f() { }

只需将其公开即可.这是基准解决方案,但如果其他解决方案都有重大缺点,这最终可能是最好的解决方案.

Just make it public. This is the baseline solution, but if the others turn out to have major disadvantages, this can end up the best one.

@PublishedApi 内部乐趣 f() { }

Kotlin 1.1-M04<中引入,注释可以应用于内部成员,使其有效地公开.我注意到的含义是任何库用户仍然可以从 Java 代码调用它,这就是我不喜欢它的地方.

Introduced in Kotlin 1.1-M04, the annotation can be applied to an internal member, making it effectively public. The implication I noticed is that any library user will still be able to call it from Java code, that's what I don't like about it.

@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") 内联 fun g() { f() }

发现于 std/a>,当应用于调用函数时,这个注解似乎抑制了错误.但它的局限性是什么?它只能用于 inline 函数吗?在某些情况下,生成的程序会失败吗?我试图用这个技巧从内联函数中调用非内联函数,它奏效了,但看起来很可疑.

Found in the stdlib sources, this annotation seems to suppress the error when applied to the calling function. But what are its limitations? Can it only be used for inline functions? Will the resulting program fail under some circumstances? I tried to call a non-inline function from an inline one with this trick, and it worked, but it looks suspicious.

@JvmSynthetic @PublishedApi 内部乐趣 f() { }

将第二种解决方案与字节码中的 synthetic 标志结合起来.我不确定这是否是 @ 的正确用法JvmSynthetic,但这似乎对Java代码隐藏了该功能,解决了@PublishedApi内部的问题.

Combine the second solution with the synthetic flag in the bytecode. I'm not sure if this is a correct usage of @JvmSynthetic, but this appears to hide the function from Java code, which solves the problem of the @PublishedApi internal.

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

So, which of these solutions is the best way call a non-public function from a public inline one? What are the downsides of each solution that I don't see?

推荐答案

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

@PublishedApi internal is the intended way of exposing non-public API for using in public inline functions.

那个 @PublishedApi 内部 成员实际上是公开的,它的名字不会被破坏(如果你注意到相反的情况,请提交错误).

That @PublishedApi internal member becomes effectively public and its name doesn't get mangled (if you noticed the opposite, please file a bug).

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

@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") is a band-aid workaround in the lack of @PublisedApi based on suppressing an error and therefore isn't recommended. With the introduction of @PublishedApi this suppression is going to be cleaned from stdlib.

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

@JvmSynthetic combined with @PublishedApi is an interesting approach, however it can cause some problems while debugging, though I'm not sure.

这篇关于内联函数无法访问非公共 API:@PublishedApi vs @Suppress vs @JvmSynthetic的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆