我想知道是否有可能创建一个泛型类,接受类型T
的实例,这仅限于(例如)String
的实例或List<String>
的实例。下面的伪代码是一个例子:
data class Wrapper<T : String | List<String>>(val wrapped: T)
这非常类似于Union
结构,它在Kotlin中不存在(设计上的)。我很好奇这是否可以在编译时检查中实现。上面提供的伪代码类将用于提供String
的单个对象实例,如果提供了多个实例,那么它应该是List<String>
。
解决这个问题的其他选项包括:
- 每个"变量"单独的类,即:
这里的缺点显然是部分重复代码。data class Wrapper<T : String>(val wrapped: T) data class ListWrapper<T : List<String>>(val wrapped: T)
- 删除上界,并使用
init
块进行实例类型检查。这里的缺点是检查移到了运行时。
编辑:我知道使用where
关键字有多个上限,但是,这会导致对符合两个上限的可接受类型的限制(因此,它是AND
结构)
虽然您所要求的在Kotlin目前是不可能的,但可能有一些替代方案。
一个选项是为数据类提供两个构造函数。默认构造函数将取元素列表,而次要元素要么接受单个/变量元素:
data class Wrapper<T : String>(val wrapped: List<T>) {
constructor(vararg wrapped: T) : this(wrapped.toList())
}
Uage:
val list = Wrapper(listOf("a", "b", "c"))
val single = Wrapper("a")
val multiple = Wrapper("a", "b", "c")
一个缺点是您的wrapped
属性将始终是一个列表。尽管在某些用例中,这可能是一件好事。