以下不起作用,但希望能帮助您理解我的意思:
class Example<T : DataClass>
Run Code Online (Sandbox Code Playgroud)
如果你想知道我想要完成什么,这就是我想到的一个例子:
class Repository<T> where T : Entity, // Entity defines mutable property 'id'
T : DataClass {
// assume there is a map here
fun add(obj: T) {
val copy = obj.copy(id = generateID())
map.put(copy.id, copy)
}
}
Run Code Online (Sandbox Code Playgroud)
或者有更好的方法来完成我想要做的事情吗?
我觉得你真正想要的是T应该能够用一个新的ID复制自己,并且有一个ID.不一定是数据类.所以你可以使用一个接口来定义它.
例如:
interface CopyableWithId<out T> where T: CopyableWithId<T> {
fun copy(newId: Long): T
val id: Long
}
data class BarBaz(override var id: Long, var name: String): CopyableWithId<BarBaz> {
override fun copy(newId: Long): BarBaz = copy(id = newId)
}
class Repository<T> where T : CopyableWithId<T>{
val map: MutableMap<Long, CopyableWithId<T>> = HashMap()
fun add(obj: T) {
val copy = obj.copy(generateID())
map.put(copy.id, copy)
}
private fun generateID(): Long {
return 1L
}
}
Run Code Online (Sandbox Code Playgroud)
不,data类在类型系统中没有任何特定的表示,并且无法与常规类区分开(类似的问题)。
data但是,您可以使用接口来要求具有一定数量组件的类具有的方法(实际上它将是data类上的标记接口)。
data下面是具有两个组件的类的示例:
interface Data2<T1, T2> {
operator fun component1(): T1
operator fun component2(): T2
fun copy(t1: T1, t2: T2): Data2<T1, T2>
}
Run Code Online (Sandbox Code Playgroud)
toString,hashCode和equals无论如何都可以在任何类型上调用。
然后只需data用接口标记你的类:
data class Impl(val i: Int, val s: String): Data2<Int, String>
val d: Data2<Int, String> = Impl(1, "2")
val (c1, c2) = d
val copy = d.copy(-1, d.component2())
Run Code Online (Sandbox Code Playgroud)
copyfunction 并不完全类型安全,因为 Kotlin没有 self 类型(并且无法要求接口实现是特定类型的子类型),但如果您只用data它标记您的类,它应该可以工作(请参阅下面的另一个选项)。
另一个缺点是您会丢失copy方法的默认参数,并且必须使用指定的所有参数来调用它:
val d = myD2.copy(newValue, myD2.component2())
Run Code Online (Sandbox Code Playgroud)
另一种选择是将这些接口定义为Data2<T1, T2, out Self>、class Impl(...): Data2<..., Impl>和 make copyreturn Self,但如果将接口用作 ,则不会有任何改善Data2<SomeType, SomeType, *>。
| 归档时间: |
|
| 查看次数: |
2828 次 |
| 最近记录: |