你的
Totals
类需要泛型类型参数,但您没有在示例的构造函数中指定泛型类型参数。其工作方式是使用类型推断:Kotlin编译器从其他参数中计算出泛型类型。你可以混合的原因
Single
Split
WRONG
例如,编译器看到这两个参数并从中推断出公共超类型。所以你实际上是在构建一个
Totals<Splittable<Int>>
.
如果显式指定子类型,则无法混合:
val WRONG = Totals<Single<Int>>(
people = Single(3),
things = Split(4, 40) /** Type inference failed. Expected type mismatch: inferred type is Split<Int> but Single<Int> was expected */
)
所以你要做的是接受
Splittable
可拆分的
本身作为泛型参数。
您可以通过子类的附加接口和附加的
generic constraint
where
-条款:
sealed class Splittable<T>
interface ConcreteSplittable
data class Single<T>(val single: T) : Splittable<T>(), ConcreteSplittable
data class Split<T>(val before: T,
val after : T) : Splittable<T>(), ConcreteSplittable
data class Totals<SInt : Splittable<Int>>(
val people : SInt,
val things : SInt
) where SInt : ConcreteSplittable
val t1 = Totals<Single<Int>>(
people = Single(3),
things = Single(4)
)
val t2 = Totals(
people = Split(3, 30),
things = Split(4, 40)
)
val WRONG = Totals( /** Type parameter bound for SInt in constructor Totals<SInt : Splittable<Int>>(people: SInt, things: SInt) where SInt : ConcreteSplittable is not satisfied: inferred type Any is not a subtype of Splittable<Int> */
people = Single(3),
things = Split(4, 40)
)
不幸的是,您也不能引入第三个类型参数
S
SInt
和
SBool
S
Splittable<Int>
或
Splittable<Bool>
data class TotalsMore<S, SInt, SBool>
(
val people : SInt,
val things : SInt,
val happy : SBool
) where S : ConcreteSplittable,
SInt : S,
SInt : Splittable<Int>, /** Type parameter cannot have any other bounds if it's bounded by another type parameter */
SBool : S,
SBool : Splittable<Boolean> /** Type parameter cannot have any other bounds if it's bounded by another type parameter */
您可以做的是创建“安全”类型别名,如下所示:
data class TotalsMore<SInt : Splittable<Int>, SBool : Splittable<Boolean>> (
val people : SInt,
val things : SInt,
val happy : SBool )
typealias SingleTotalsMore = TotalsMore<Single<Int>, Single<Boolean>>
typealias SplitTotalsMore = TotalsMore<Split<Int>, Split<Boolean>>
val s = SingleTotalsMore(
people = Single(3),
things = Single(4),
happy = Single(true) )
创建混合
TotalsMore