gpt4 book ai didi

Kotlin 高阶函数参数 : Passing subtypes

转载 作者:行者123 更新时间:2023-12-04 19:26:18 25 4
gpt4 key购买 nike

我在 Kotlin 中遇到了函数参数问题。我将在一些代码的帮助下解释这个问题。

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

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
}

我试图用函数参数来模拟这一点。
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 的子类型.
解决这个问题的最佳方法是什么?

我原来的问题是在 A.h 中定义一个高阶函数接受一个函数 z: (A) -> X作为参数。我想打电话 hB 类型的对象上并传递一个函数 z: (B) -> X .

更新:
我尝试了有上限的泛型,但我的问题没有解决。请在下面找到代码:
// 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
}
}

最佳答案

您要做的是从函数类型 (B) -> Int 的转换(来源)至 (A) -> Int (目标)。这不是一个安全的转换。

您的源函数 (B) -> Int接受任何一个 B 的实例, 但不一定是 A 类型的实例 .更具体地说,它不能处理所有类型为 A 的参数。但不是类型 B .

想象一下你的类是这样的:

open class A
class B : A {
fun onlyB() = 29
}

你可以定义一个函数
val fb: (B) -> Int = { it.onlyB() }
val fa: (A) -> Int = fb // ERROR

函数 fb将无法对类 A 进行操作, 自 A没有 onlyB()功能。因此,您不能将其转换为采用 A 的函数类型。参数。

这个概念叫做逆变,意思是输入参数只能通过变成 来约束。更具体 ,不再抽象。因此,相反的方向起作用:
val fa: (A) -> Int = { it.hashCode() }
val fb: (B) -> Int = fa // OK, every B is also an A

相反,对于返回值,协方差的概念适用。这意味着允许返回值变为 更抽象 ,但不是更具体:
val fInt: (B) -> Int = { it.onlyB() }
val fNum: (B) -> Number = fInt // OK, every Int is also a Number

可以使用 Kotlin 的 in 在泛型类中利用这些关系。 (逆变)和 out (协方差)关键字——见 here详细解释。

关于Kotlin 高阶函数参数 : Passing subtypes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55572345/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com