У меня есть общий запечатанный класс, используемый для представления либо отдельных значений, либо пар значений (разделенных до и после определенного события):
sealed class Splittable<T>
data class Single<T>(val single: T) : Splittable<T>()
data class Split<T>(val before: T,
val after : T) : Splittable<T>()
Я хотел бы определить классы данных, которые являются общими (параметризуемыми) поверх Splittable
, чтобы свойства класса должны были либо быть все Single, либо все Split. Я думал, что это будет сделано:
data class Totals<SInt : Splittable<Int>>(
val people : SInt,
val things : SInt
)
val t1 = Totals(
people = Single(3),
things = Single(4)
)
val t2 = Totals(
people = Split(3, 30),
things = Split(4, 40)
)
Но я ошибся, потому что он допускает недопустимые комбинации:
val WRONG = Totals(
people = Single(3),
things = Split(4, 40)
)
Более того, что, если мой класс имеет более одного базового типа, например, и Int
, и Boolean
? Как написать общую подпись?
data class TotalsMore<S : Splittable>(
val people : S<Int>,
val things : S<Int>,
val happy : S<Boolean>
)
val m1 = TotalsMore(
people = Single(3),
things = Single(4),
happy = Single(true)
)
val m2 = TotalsMore(
people = Split(3, 30),
things = Split(4, 40),
happy = Split(true, false)
)
Объявление класса данных дает ошибки:
error: one type argument expected for class Splittable<T>
data class TotalsMore<S : Splittable>(
^
error: type arguments are not allowed for type parameters
val people : S<Int>,
^
error: type arguments are not allowed for type parameters
val things : S<Int>,
^
error: type arguments are not allowed for type parameters
val happy : S<Boolean>
^
Итак, похоже, я не могу передать тип более высокого типа в качестве параметра типа. облом.
Я могу разделить два дженерика:
data class TotalsMore<SInt : Splittable<Int>,
SBoolean: Splittable<Boolean>>(
val people : SInt,
val things : SInt,
val happy : SBoolean
)
Это работает, но делает еще более очевидным, что вы можете смешивать и сочетать Single и Split, что я хочу запретить:
val WRONG = TotalsMore(
people = Single(3),
things = Single(4),
happy = Split(true, false)
)
Я хотел бы, чтобы каждый объект этих классов данных состоял либо из всех значений Single, либо из всех значений Split, а не из смешивания и сопоставления.
Могу ли я выразить это, используя типы Котлина?