kotlin - Kotlin:在通用函数中访问伴随数据
问题描述
我在 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???}"
}
我不想要的一件事是使用 non-companion defaultValue
,我总是必须手动将它传递给函数(但是为什么如果类型包含所有信息?)或者,如果设为非伴随:
interface DisplayableEnum<E: Enum<E>> {
val displayValue: String
val defaultValue: E
}
然后通过一个对象访问它——做一些丑陋的事情,比如enumValues<T>().first().defaultValue
.
我想知道 Kotlin 在这种情况下是否有解决方案。
解决方案
在伴生对象中定义抽象属性是不可能的。所以应该直接在接口中定义。
这里棘手的部分是在没有编译器警告的情况下实现这个接口:
enum class MyEnum(override val displayValue: String) : DisplayableEnum<MyEnum> {
A("value is A"),
B("value is B");
override val defaultValue: MyEnum by lazy { A }
}
如果enumValues<T>().first().defaultValue
你觉得难看,请将其包装到辅助函数中:
inline fun <reified T> enumDefaultValue(): T where T : Enum<T>, T : DisplayableEnum<T> =
enumValues<T>().first().defaultValue
//Usage:
println("Default value: ${enumDefaultValue<T>()}")
推荐阅读
- c - 计算页面错误和代码换出
- python - VsCode-每次打开Python文件时“在终端中运行Python文件”都会消失
- laravel - 如何添加可以与 Auth() 函数链接的自定义函数?
- python - 在 Outliner Maya 中将对象类型分组
- jboss - "WFLYCTL0412: 未安装的所需服务:" => ["jboss.jdbc-driver.mysql"]
- html - VBA HTML 拉取需要加速
- mysql - 如何在日期之间从mysql数据库中选择一个名称
- c# - 未按预期循环遍历数组
- angular - 如何进行项目修改以将 Asp .net Core Angurlar 6 捆绑包存储在 CDN 中
- c - Does the C language specify a stack?