No, data
Le classi non hanno alcuna rappresentazione specifica nel sistema di tipi e non possono essere distinte dalle classi regolari (similar question).
È tuttavia possibile richiedere i metodi a una classe data
con un determinato numero di componenti che utilizza un'interfaccia (in realtà sarà un'interfaccia marker sulle classi data
).
Ecco un esempio per data
classi con due componenti:
interface Data2<T1, T2> {
operator fun component1(): T1
operator fun component2(): T2
fun copy(t1: T1, t2: T2): Data2<T1, T2>
}
toString
, hashCode
e equals
può essere chiamato su qualsiasi tipo comunque.
Poi basta contrassegnare la classe data
con l'interfaccia:
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())
copy
funzione non è di tipo-safe completamente a causa Kotlin doesn't have self type (e non c'è modo di richiedere implementazioni di interfacce di essere sottotipo di un tipo specifico), ma se contrassegni solo le tue classi data
, dovrebbe funzionare (vedi un'altra opzione sotto).
Un altro svantaggio è che si perde parametri di default di copy
metodo e dovuto chiamare con tutti i parametri specificati:
val d = myD2.copy(newValue, myD2.component2())
Un'altra opzione è quella di definire queste interfacce come Data2<T1, T2, out Self>
, class Impl(...): Data2<..., Impl>
, e make copy
restituisce Self
, ma non lo renderà migliore se si utilizza l'interfaccia come Data2<SomeType, SomeType, *>
.