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