Nie, data
klasy nie mają określonej reprezentacji w systemie typu i nie można ich odróżnić od klas regularnych (similar question).
Można jednak wymagać zastosowania metod klasy data
z pewną liczbą komponentów przy użyciu interfejsu (w rzeczywistości będzie to interfejs znacznika w klasach data
).
Oto przykład dla data
klas z dwóch komponentów:
interface Data2<T1, T2> {
operator fun component1(): T1
operator fun component2(): T2
fun copy(t1: T1, t2: T2): Data2<T1, T2>
}
toString
, hashCode
i equals
można nazwać na wszelkiego rodzaju tak.
Następnie wystarczy zaznaczyć swoją klasę data
z interfejsem:
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
funkcja nie jest całkowicie wpisać bezpieczny ponieważ Kotlin doesn't have self type (i nie sposób wymagać implementacje interfejsu być podtypem określonego typu), ale jeśli oznaczysz je swoimi klasami data
, powinno działać (zobacz inną opcję poniżej).
Inną wadą jest to, że można stracić domyślne parametry copy
metody i trzeba nazwać ze wszystkimi parametrami określonymi:
val d = myD2.copy(newValue, myD2.component2())
Inną opcją jest określenie tych interfejsów jak Data2<T1, T2, out Self>
, class Impl(...): Data2<..., Impl>
i make copy
return Self
, ale nie zrobi to lepiej, jeśli użyjesz interfejsu jako Data2<SomeType, SomeType, *>
.