所以,我一直在Kotlin反思中徘徊,而我似乎无法做到以下几点:
object ThreadState {
sealed class State {
object DANCE : State() {val validEvents: List<ThreadEvent> = listOf(ThreadEvent.Weave, ThreadEvent.Bob)}
object DUCK : State() {val validEvents: List<ThreadEvent> = listOf(ThreadEvent.Weave, ThreadEvent.Bob)}
object DODGE : State() {val validEvents: List<ThreadEvent> = listOf(ThreadEvent.Weave, ThreadEvent.Bob)}
.... Code
}
.... Code
}
我想做的是这样的:
val map = ThreadState.State::class.sealedSubclasses.map{ it to it.simpleName}.toMap()
map[ThreadState.State.DODGE]
让它吐出类的简单名称(在本例中为DODGE)。
原因是因为我可以简单地反转地图并从名称中获取值。即ThreadState.fromString("DODGE") // ThreadState.State.DODGE
但是,当我使用:: sealedSubclasses时,它会给出<KClass <out ThreadState.State>>
的列表
这不是布宜诺斯艾利斯,因为我一生无法找到从KClasses列表中的任何给定元素中撤回ThreadState.State
的方法。我尝试运行it as ThreadState.State
,但它告诉我不能将KClass强制转换为ThreadState.State。
任何帮助将不胜感激。
简而言之-列出密封类的列表,这些密封类是包含值的单例对象。需要制作符合<ThreadState, String>
的类的映射,其中ThreadState是ThreadState.State的实例,而字符串只是该类的简单名称。
我真的很愿意接受解决方案-当然不必反思,也欢迎泛型。
答案 0 :(得分:2)
您在这里:
val stateMap = ThreadState.State::class.sealedSubclasses.asSequence()
.map { it.simpleName to it.objectInstance } // note the objectInstance call
.toMap()
还要注意objectInstance
的文档:
对象声明的实例;如果此类不是对象声明,则为
null
。
出于测试目的,我在您的State
类中添加了以下功能:
fun printMe() = println("class: ${this::class.simpleName} object: $this")
现在您可以按以下方式访问对象:
stateMap["DODGE"]?.printMe()
// will then print the same as:
ThreadState.State.DODGE.printMe()
我想走那条路值得,但是您知道用例,我不……也许delegated properties之类的东西对您有用吗?
但是:如果要访问validEvents
,则需要确保它也是State
类本身的一部分,即,您可能需要添加如下内容:
sealed class State {
open val validEvents : List<ThreadEvent> = emptyList()
// and then of course the subclasses need to override it:
object DANCE : State() {override val validEvents: List<ThreadEvent> = listOf(ThreadEvent.Weave, ThreadEvent.Bob)}
只有这样,您才能拨打类似的电话:
stateMap["DODGE"]?.validEvents
答案 1 :(得分:1)
map[ThreadState.State.DODGE::class]
怎么样?还是不适合您?