【发布时间】:2020-12-04 01:02:28
【问题描述】:
我在 Kotlin 中有一个列出枚举值的简单任务:
interface DisplayableEnum<E: Enum<E>> {
val displayValue: String
}
inline fun <reified T> printAllValues(selected: T?) where T: Enum<T>, T: DisplayableEnum<T> {
println("All Values:")
enumValues<T>().forEach {
println(it.displayValue)
}
selected?.let { println("\nSelected: ${it.displayValue}") }
}
////// USAGE
enum class MyEnum(override val displayValue: String): DisplayableEnum<MyEnum> {
A("value is A"),
B("value is B")
}
fun main() {
// with a selected value
f(MyEnum.A)
// without a selected value
f(null as MyEnum?)
}
现在假设我传递给printAllValues 的所有枚举也应该有一个名为defaultValue 的字段。如果是MyEnum,我会这样写:
enum class MyEnum(override val displayValue: String): DisplayableEnum<MyEnum> {
A("value is A"),
B("value is B");
companion object {
val defaultValue = A
}
}
所以我的问题是:有没有办法在 Kotlin 中定义这样的合同?
理想情况下,我想以某种方式在接口中定义该合约,例如上面的DisplayableEnum,然后以某种方式在printAllValues 中使用它,如下所示:
inline fun <reified T> printAllValues(selected: T) where T: Enum<T>, T: DisplayableEnum<T> {
println("All Values:")
enumValues<T>().forEach {
println(it.displayValue)
}
selected?.let { println("\nSelected: ${it.displayValue}") }
println("Default value: ${T.defaultValue???}"
}
我不想要的一件事是使用非伴随 defaultValue,我总是必须手动将它传递给函数(但是为什么如果类型包含所有信息?)或者,如果非同伴:
interface DisplayableEnum<E: Enum<E>> {
val displayValue: String
val defaultValue: E
}
然后通过一个对象访问它——做一些丑陋的事情,比如enumValues<T>().first().defaultValue。
我想知道 Kotlin 是否有针对这种情况的解决方案。
【问题讨论】:
-
不,同伴是完全不同的对象,你不能通过其他类的实例来引用它们。