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

问题描述

我想知道是否可以创建一个泛型类,它接受类型为 T 的实例,该实例仅限于(例如)String 的实例或 {{1} 的实例}}。以如下伪代码为例:

List<String>

这与 data class Wrapper<T : String | List<String>>(val wrapped: T) 结构非常相似,后者在 Kotlin 中不存在(按设计)。我很好奇这是否可以在编译时检查中实现。 上面提供的伪代码类将用于提供 Union 的单个对象实例,如果提供多个​​实例,则它应该是一个 String

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

  1. 每个“变体”的单独类,即:
    List<String>
    明显的缺点是它是部分重复的代码
  2. 移除上限,并使用 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 属性将始终是一个列表。尽管在某些用例中这可能是一件好事。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...