具有接收器的功能的Kotlin扩展功能

时间:2019-11-07 00:32:39

标签: kotlin higher-order-functions typing receiver extension-function

我正在使用Kotlin的扩展功能。 我想为带有接收器的布尔返回函数创建扩展函数,该函数返回补码函数。

我的目标是能够写:

val isEven: Int.() -> Boolean = { this % 2 == 0 }
val isOdd: Int.() -> Boolean = isEven.complement()

我确实知道有更好,更清晰的方式来做我正在做的事情,我想在这里更好地理解语言本身,所以请不要告诉我将isOdd写成{ !isEven() } :)

我想要类似的东西

fun <I> (I.() -> Boolean).complement(): I.() -> Boolean = TODO()

现在,

fun <I> (I.() -> Boolean).complement(): I.() -> Boolean = this

正确编译,因此语法在这里绝对有意义。问题是this的类型为I.() -> Boolean,我需要使用接收器(例如this@this)访问函数的“内部接收器”,以编写如下内容:< / p>

fun <I> (I.() -> Boolean).complement(): I.() -> Boolean = { !(this@this).this() }

其中this@this的类型为I。有什么办法可以达到这种效果?

此外,我注意到我不知道如何使用接收器调用函数,我试图:

fun <I> (I.() -> Boolean).complement(innerthis: I): I.() -> Boolean = { !this(innerthis) }

我得到一个error: expression 'this' of type 'I' cannot be invoked as a function. The function 'invoke()' is not found

这听起来对我来说是错的! this的类型应为I.() -> Boolean,而不是I!我无法绕过这个错误消息。

我认为也许我只是使用了错误的语法,所以我改为:

fun <I> (I.() -> Boolean).complement(innerthis: I): I.() -> Boolean = { !innerthis.this() }

但是我得到了同样的错误。正如我所期望的那样,innerthis的类型为I,而this的类型为I.() -> Boolean。 我的期望似乎已通过= this的实现得到了完美的编译。

有人可以向我解释编译器引发的错误吗?

谢谢!

1 个答案:

答案 0 :(得分:3)

您可以通过函数名称消除外部this的歧义:

fun <I> (I.() -> Boolean).complement(): I.() -> Boolean = { !this@complement(this) }

这里this@complementcomplement函数的接收者,而普通this是lambda函数文字的接收者。为简单起见,this@complement就像一个带有一个参数的函数一样被调用,但是也可以使用一些更棘手的语法将其称为扩展函数:

fun <I>  (I.() -> Boolean).complement(): I.() -> Boolean = { !this.(this@complement)() }