如何定义一个接受具有特定字段的任何数据类的函数

Yoh*_*hei 2 kotlin

例如,我想要一个foo接受两者AB在外部包中定义的函数,如下所示:

fun foo<T: { p: Int }>(x: T) {}

data class A(val p: Int, val a: Int)
data class B(val p: Int, val b: Int)
Run Code Online (Sandbox Code Playgroud)

我尝试了Interface,但似乎需要更新A和B的定义,但我不能这样做,因为它们是在外部包中定义的。

我想要在 TypeScript 中做的是这样的:

fun foo<T: { p: Int }>(x: T) {}

data class A(val p: Int, val a: Int)
data class B(val p: Int, val b: Int)
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

Swe*_*per 6

与 TypeScript 不同,Kotlin 不使用结构类型,因此您只能通过使用接口来强制执行此操作。

如果你做不到这一点,那么你必须要求调用者foo通过使用额外的参数来为你提供你需要的属性

fun <T> foo(x: T, p: KProperty1<T, Int>) {
    println(p.get(x)) // example access
}
Run Code Online (Sandbox Code Playgroud)

用法示例:

foo(A(1, 2), A::p)
Run Code Online (Sandbox Code Playgroud)

与使用接口的一个主要区别是调用者可以使用Int上的任何属性A。它不必被称为p

除此之外,您唯一的选择是在运行时强制执行此操作,方法是在找不到属性时抛出异常。