Kotlin 泛型多个上限(作为 OR / union 构造)

Rob*_*sch 5 generics upperbound kotlin

我想知道是否有可能创建一个泛型类,它接受一个 type 的实例T,它仅限于(例如) 的实例String或 的实例List<String>。以如下伪代码为例:

data class Wrapper<T : String | List<String>>(val wrapped: T)
Run Code Online (Sandbox Code Playgroud)

这非常类似于UnionKotlin 中不存在的构造(按设计)。我很好奇这是否可以在编译时检查中实现。上面提供的伪代码类将用于提供 的单个对象实例String,如果提供了多个实例,则它应该是一个List<String>.

解决此问题的其他选项包括:

  1. 每个“变体”的单独类,即:
    data class Wrapper<T : String>(val wrapped: T)
    data class ListWrapper<T : List<String>>(val wrapped: T)
    
    Run Code Online (Sandbox Code Playgroud) 这里的缺点显然是它是部分重复的代码。
  2. 删除上限,并使用init块进行实例类型检查。这里的缺点是检查移动到运行时。

编辑:我知道使用关键字有多个上限where,但是,这会导致对符合两个上限的接受类型的限制(因此,它是一个AND构造)

Jak*_*las 1

虽然您所要求的在 Kotlin 当前是不可能的,但可能没有其他选择。

一种选择是为数据类提供两个构造函数。默认构造函数将采用元素列表,而辅助构造函数将采用单个/变量元素:

data class Wrapper<T : String>(val wrapped: List<T>) {
    constructor(vararg wrapped: T) : this(wrapped.toList())
}
Run Code Online (Sandbox Code Playgroud)

你的年龄:

val list = Wrapper(listOf("a", "b", "c"))
val single = Wrapper("a")
val multiple = Wrapper("a", "b", "c")
Run Code Online (Sandbox Code Playgroud)

一个缺点是您的wrapped财产将始终是一个列表。尽管在某些用例中这可能是一件好事。