【问题标题】:How can I inline the receiver parameter of an extension function in Kotlin?如何在 Kotlin 中内联扩展函数的接收器参数?
【发布时间】: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 &lt;T&gt; ((T) -&gt; Boolean).not(): (T) -&gt; Boolean 的预期性能影响微不足道。内联最适合带有函数类型参数的函数

这让我相信编译器没有内联该函数的接收器。添加inlinecrossinline 只会产生语法错误。

无法内联第二个函数会降低第一个函数的性能。

有没有办法告诉编译器内联接收器参数?

【问题讨论】:

  • 最初我只是想回答只有带有 lambda 参数的函数是内联的......但是,至少在 Java 中,这两个函数实际上都变成了底层的静态方法,并且可能看起来一样,我也期望同样的... crossinline 在第二个也是可能的...但也许这只是 Java 的情况,而在其他语言中情况并非如此?
  • @Roland 内联不被 java 编译器支持。如果一个函数被标记为inline,那么它的 lambda 参数只有在您从 Kotlin 使用编译器可以内联的 lambda 调用它时才会被内联。但是,receiver参数是一个有特殊语法和特殊处理的参数,但是我看不出编译器不能内联它的原因
  • 我知道......我的意思是扩展函数也将翻译......它基本上是一样的......这也是如果你同时实现 JVM 名称冲突的原因方法。
  • @Roland 你是对的,都翻译成public static final &lt;T&gt; kotlin.jvm.functions.Function1&lt;T, java.lang.Boolean&gt; not(kotlin.jvm.functions.Function1&lt;? super T, java.lang.Boolean&gt;);。然而这并不重要,因为翻译后的 jvm 签名根本没有内联信息(别忘了 kotlin 也可以编译为 javascript)
  • 是的......我认为我的英语没有我希望的那么好(或者我太累了);-) 关于其他语言,例如javascript:我试图在第一条评论中说...显然,评论没有到达。 :-)

标签: kotlin inline extension-function


【解决方案1】:

这在 https://youtrack.jetbrains.com/issue/KT-5837 中被跟踪,但似乎并没有被积极处理 :( 实际上我 just suggested supporting noinline/crossinline 希望这是接收器没有内联的主要原因。

【讨论】:

    猜你喜欢
    • 2020-03-03
    • 2018-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多