Kotlin高阶函数参数:传递子类型

问题描述:

我在Kotlin中遇到函数参数问题.我将借助一些代码来解释这个问题.

I have run into a problem with function parameters in Kotlin. I will explain the issue with the help of some code.

我创建了一个类层次结构.当我将子类型传递给需要父类型的函数时,没有问题.

I created a class hierarchy. When I pass a subtype into a function expecting a parent type, there is no issue.

open class A (val i: Int)
class B (val j: Int) : A(j)

fun f(x: A){
    print(x)
}

fun test_f(){
    f(A(1))
    f(B(1)) //no problem
}

我试图用函数参数来模仿它.

I tried to mimic this with function parameters.

fun g(x: (A)->Int){
    print(x)
}

fun test_g(){
    val l1 = { a: A -> a.hashCode()}
    g(l1)

    val l2 = { b: B -> b.hashCode()}
    g(l2) //Error: Type mismatch. Required: (A)->Int, Found: (B)->Int
}

函数类型(B) -> Int似乎不是(A) -> Int的子类型. 解决此问题的最佳方法是什么?

It seems that function type (B) -> Int is not a subtype of (A) -> Int. What is the best way to address this?

我最初的问题是在A.h中定义一个以函数z: (A) -> X为参数的高阶函数.我想在类型为B的对象上调用h并传递一个函数z: (B) -> X.

My original problem is to define a higher order function in A.h that takes a function z: (A) -> X as parameter. And I want call h on an object of type B and pass a function z: (B) -> X.

更新: 我尝试了具有上限的泛型,但我的问题没有解决.请在下面找到代码:

Update: I tried generics with upper bound, yet my issue is not solved. Please find code below:

// Using generics doesn't allow me to pass A.
open class A (val i: Int) {
    fun <M: A> g(x: (M)->Int){
        print(x(this)) // Error: Type mismatch. Expected: M, Found: A 
    }
}

您可以使用通用扩展函数.从更新后的示例派生扩展功能:

You can solve it using generics and an extension function on a generic receiver. Deriving the extension function from your updated sample:

fun <T : A> T.g(x: (T)->Int){
    print(x(this))
}

这样,可以确保接收方和给定函数的第一个参数类型相同,这是A或其子类型.

This way it is ensured that the receiver and the first parameter type of the given function are the same, which is either an A or a subtype of it.