【发布时间】:2019-02-03 02:14:00
【问题描述】:
受this question 的启发,我在想如何内联扩展函数的接收器参数?理论上是这样的:
inline fun <T> not(crossinline predicate : (T) -> Boolean)
= { e : T -> !predicate(e) }
只是 predicate 成为我们的接收函数:
operator inline fun <T> ((T) -> Boolean).not()
= { e : T -> !this(e) }
现在,对于上面的代码,我希望编译器会抱怨它需要crossinline;但是,我收到以下警告:
警告:内联
public inline operator fun <T> ((T) -> Boolean).not(): (T) -> Boolean的预期性能影响微不足道。内联最适合带有函数类型参数的函数
这让我相信编译器没有内联该函数的接收器。添加inline 或crossinline 只会产生语法错误。
无法内联第二个函数会降低第一个函数的性能。
有没有办法告诉编译器内联接收器参数?
【问题讨论】:
-
最初我只是想回答只有带有 lambda 参数的函数是内联的......但是,至少在 Java 中,这两个函数实际上都变成了底层的静态方法,并且可能看起来一样,我也期望同样的...
crossinline在第二个也是可能的...但也许这只是 Java 的情况,而在其他语言中情况并非如此? -
@Roland 内联不被 java 编译器支持。如果一个函数被标记为
inline,那么它的 lambda 参数只有在您从 Kotlin 使用编译器可以内联的 lambda 调用它时才会被内联。但是,receiver参数是一个有特殊语法和特殊处理的参数,但是我看不出编译器不能内联它的原因 -
我知道......我的意思是扩展函数也将翻译......它基本上是一样的......这也是如果你同时实现 JVM 名称冲突的原因方法。
-
@Roland 你是对的,都翻译成
public static final <T> kotlin.jvm.functions.Function1<T, java.lang.Boolean> not(kotlin.jvm.functions.Function1<? super T, java.lang.Boolean>);。然而这并不重要,因为翻译后的 jvm 签名根本没有内联信息(别忘了 kotlin 也可以编译为 javascript) -
是的......我认为我的英语没有我希望的那么好(或者我太累了);-) 关于其他语言,例如javascript:我试图在第一条评论中说...显然,评论没有到达。 :-)
标签: kotlin inline extension-function