在Kotlin阅读和处理HOCON

Geo*_*ath 5 kotlin typesafe-config hocon

我想从HOCON(Typesafe配置)文件中读取以下配置到Kotlin.

tablename: {  
  columns: [
    { item: { type: integer, key: true, null: false } }
    { desc: { type: varchar, length: 64 } }
    { quantity: { type: integer, null: false } }
    { price: { type: decimal, precision: 14, scale: 3 } }
  ]
}
Run Code Online (Sandbox Code Playgroud)

实际上我想提取关键列.到目前为止,我已尝试过以下内容.

val metadata = ConfigFactory.parseFile(metafile)
val keys = metadata.getObjectList("${tablename.toLowerCase()}.columns")
                   .filter { it.unwrapped().values.first().get("key") == true }
Run Code Online (Sandbox Code Playgroud)

但它失败并出现以下错误.

Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
@kotlin.internal.InlineOnly public operator inline fun <@kotlin.internal.OnlyInputTypes K, V> kotlin.collections.Map<out kotlin.String, ???>.get(key: kotlin.String): ??? defined in kotlin.collections
Run Code Online (Sandbox Code Playgroud)

很明显,Kotlin无法理解Map中"value"字段的数据类型.我如何申报或让Kotlin知道?

也不是说这个Map中有不同的类型和可选键.

PS:我知道Kotlin有几种包装,如Konfig和Klutter.我希望如果这很容易写,我可以避免另一个库.

更新1:

我尝试了以下内容.

it.unwrapped().values.first().get<String, Boolean>("key")
Run Code Online (Sandbox Code Playgroud)

获取以下编译器错误.

Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
@kotlin.internal.InlineOnly public operator inline fun <@kotlin.internal.OnlyInputTypes K, V> kotlin.collections.Map<out kotlin.String, kotlin.Boolean>.get(key: kotlin.String): kotlin.Boolean? defined in kotlin.collections
Run Code Online (Sandbox Code Playgroud)

还有这个

it.unwrapped().values.first().get<String, Boolean?>("key")
Run Code Online (Sandbox Code Playgroud)

与输出

Unresolved reference. None of the following candidates is applicable because of receiver type mismatch:
@kotlin.internal.InlineOnly public operator inline fun <@kotlin.internal.OnlyInputTypes K, V> kotlin.collections.Map<out kotlin.String, kotlin.Boolean?>.get(key: kotlin.String): kotlin.Boolean? defined in kotlin.collections
Run Code Online (Sandbox Code Playgroud)

更新2:

看看它在别处处理的方式,我想我可能需要使用反射.用我有限的曝光试试吧.到目前为止没有运气.

小智 8

考虑一下你的代码,解构如下:

val keys = metadata.getObjectList("tablename.columns")
        .filter {
            val item:ConfigObject = it
            val unwrapped:Map<String,Any?> = item.unwrapped()
            val values:Collection<Any?> = unwrapped.values
            val firstValue:Any? = values.first()
            firstValue.get("key") == true // does not compile
        }
Run Code Online (Sandbox Code Playgroud)

从上面来看问题应该是显而易见的.你需要的信息,以帮助编译器firstValue拥有Map像这样:

val firstValueMap = firstValue as Map<String,Any?>
firstValueMap["key"] == true
Run Code Online (Sandbox Code Playgroud)