У меня есть общий запечатанный класс, который используется для представления отдельных значений или пар значений (разделенных до и после определенного события):
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
, так что свойства класса должны быть либо одинарными, либо полностью разделенными. Я думал, что это сделает это:
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, а не из сочетания и совпадения.
Могу ли я выразить это с помощью Kotlinтипы?