4

我在玩 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,编写如下内容:

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

wherethis@this将是 type 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的那样,这对我来说非常困惑 typeIthistype I.() -> Boolean。我的期望似乎得到了实现= this完美编译的证实。

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

谢谢!

4

1 回答 1

3

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

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

这里this@complementcomplement函数的接收者,plainthis是 lambda 函数字面量的接收者。为简单起见,this@complement它被称为带有一个参数的函数,但是也可以使用更复杂的语法将其作为扩展函数调用:

fun <I>  (I.() -> Boolean).complement(): I.() -> Boolean = { !this.(this@complement)() }
于 2019-11-07T01:14:47.310 回答