Gil*_*eig 6 java java-interop kotlin kotlin-interop
这是一个普遍的问题.假设我有一个用kotlin编写的扩展函数,它将DP转换为PX并返回一个NonNull Int
fun Int.toPx() { /** implementation */ }
Run Code Online (Sandbox Code Playgroud)
java中的函数看起来像这样
public int toPx(int $receiver) { /** implementation */ }
Run Code Online (Sandbox Code Playgroud)
在我看来,这$receiver使得Java-interop感觉生成和不受欢迎.
我知道你可以使用@JvmName注释和一些组合@file:JvmName来改变java中的名字.
当我尝试使用@JvmName与receiver网站的目标,它说
"此注释不适用于目标type usage和使用站点目标@receiver"
有没有办法克服这一点并改变接收器的名称,如果不是最好的选择.
@JvmName 只能应用于文件的函数,属性访问器和顶级包外观,不支持参数名称.
基本上,您可以定义两个函数,一个采用简单参数,另一个采用接收器:
fun toPx(value: Int) { /* implementation */ }
fun Int.toPx() = toPx(this)
Run Code Online (Sandbox Code Playgroud)
但是,预计足够,这将无法编译,因为这两个函数将具有相同的JVM签名.因此,要消除它们的歧义,请添加@JvmName("...")到扩展名并(可选)标记扩展名inline以将其从Java中隐藏:
fun toPx(value: Int) { /* implementation */ }
@JvmName("toPxExtension") @Suppress("nothing_to_inline")
inline fun Int.toPx() = toPx(this)
Run Code Online (Sandbox Code Playgroud)
使内联扩展的替代方法是使用它进行注释@JvmSynthetic.但是,内联也将取消呼叫开销.
此解决方案的缺点是顶级功能toPx泄漏到查看程序包的文件的IDE完成范围.
| 归档时间: |
|
| 查看次数: |
652 次 |
| 最近记录: |