0

我正在尝试创建一个中缀符号作为函数的扩展函数,(Int) -> Int用于将函数嵌套到另一个函数。
例如:

class Entry {
    companion object {
        private fun f(x: Int) = x * 2
        private fun g(x: Int) = x + 2

        private infix fun ((Int) -> Int).nest(inner: (Int) -> Int) = { x: Int -> this(inner(x)) }

        @JvmStatic
        fun main(args: Array<String>) {
            val func = ::f nest ::g
            println(func(10))
        }
    }
}

这段代码工作正常,它创建了一个中缀符号nest作为函数的扩展(Int) -> Int函数。它需要另一个(Int) -> Int函数并将它们嵌套在一起。
val func = ::f nest ::g等于val fun func(x:Int) = f(g(x))
func(10)等于(10 + 2) * 2

但是当我尝试将此扩展notate函数扩展为Number接口时遇到了一个问题(用于支持各种数字)。
例如:

class Entry {
    companion object {
        private fun f(x: Int) = x * 2
        private fun g(x: Int) = x + 2

        private infix fun ((Number) -> Number).nest(inner: (Number) -> Number) = { x: Number -> this(inner(x)) }
        // only the infix fun declaration changed ^

        @JvmStatic
        fun main(args: Array<String>) {
            val func = ::f nest ::g
            println(func(10))
        }
    }
}

kotlin 编译器会抛出错误。

Kotlin: Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: 
private final infix fun ((Number) -> Number).nest(inner: (Number) -> Number): (Number) -> Number defined in ...(path of class Entry)

我想知道为什么Int从 延伸Number,但(Int) -> Int不匹配到(Number) -> Number
如果我想将此符号函数扩展到所有请求数字并返回数字的函数(例如(Long) -> Long (Float) -> Double等),我该怎么办?

4

1 回答 1

1

请注意,a(Int) -> Int不是一种。也就是说,您可以将 any传递给 a ,但您只能将s 传递给 a 。(Number) -> NumberNumber(Number) -> NumberInt(Int) -> Int

按照你的逻辑,我可以nesta(Int) -> Int和 a (Double) -> Double,因为(Double) -> Double也是 a (Number) -> Number(按照你的逻辑),但这当然没有意义,不是吗?您不能将 a 传递Double给 a (Int) -> Int

您的nest函数可以用泛型更一般地编写:

infix fun <T, U, V> ((U) -> V).nest(inner: (T) -> U) = { x: T -> this(inner(x)) }

可以嵌套任何(U) -> Vwith (T) -> U,产生(T) -> V.

于 2021-09-30T07:24:26.073 回答