带接收器的函数的 Kotlin 扩展函数

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

我正在使用 Kotlin 的扩展函数。 我想为 bool 返回函数创建一个扩展函数,其接收器返回补码函数。

我的目标是能够编写:

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() }

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

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

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

我收到一个错误:“I”类型的表达式“this”无法作为函数调用。找不到函数“invoke()”

这对我来说听起来不对! this 应该具有类型 I.() -> Boolean,而不是 I!我无法理解这个错误消息。

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

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

但我遇到了同样的错误。这让我很困惑,因为我期望 innerthisI 类型,而 thisI 类型。( ) -> bool 值= this 的实现似乎证实了我的期望,可以完美地编译。

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

谢谢!

最佳答案

您可以通过函数名称消除外部 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)() }

关于带接收器的函数的 Kotlin 扩展函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58740349/

相关文章:

kotlin - Kotlin 中的 Elvis "if"运算符作为函数默认参数

Javascript 宏 : implementing F# style forward pipe operator

python - 导入错误 : No module named 'typing' when trying to install a package

python - 使用 Boost::Python 进行高阶编程

scala - 函数式编程标量

typescript - 如何获得没有具体类的深度嵌套命名空间的别名?

python : using type hints to dynamically check types

Kotlin等于和哈希码生成器

performance - 如何获得一个函数在 Kotlin 中测试函数性能所需的时间

kotlin - 如果让Kotlin相当于迅捷? -对于类变量?