【问题标题】:How does Kotlin's Json.decodeFromString work without a first DeserializationStrategy argument?如果没有第一个 DeserializationStrategy 参数,Kotlin 的 Json.decodeFromString 是如何工作的?
【发布时间】:2021-01-16 11:50:08
【问题描述】:

我是 Kotlin 的新手,我很好奇是什么魔法让这段代码能够工作:

来自https://github.com/Kotlin/kotlinx.serialization/blob/e2e764a132c8eebd31208120774baf9a71ec23c7/formats/json/commonTest/src/kotlinx/serialization/SerializerForNullableTypeTest.kt

@Serializable
data class Box(val s: StringHolder?)

val deserialized = Json.decodeFromString<Box>(string)

当函数定义似乎在编码的 JSON 字符串之前需要一个初始参数时。

https://github.com/Kotlin/kotlinx.serialization/blob/e2e764a132c8eebd31208120774baf9a71ec23c7/formats/json/commonMain/src/kotlinx/serialization/json/Json.kt

public final override fun <T> decodeFromString(deserializer: DeserializationStrategy<T>, string: String): T {

【问题讨论】:

    标签: json kotlin


    【解决方案1】:

    该方法目前是 SerialFormat.kt 中实验性 API 的一部分:

    它是一个扩展函数,接口如下:

    @OptIn(ExperimentalSerializationApi::class)
    public inline fun <reified T> StringFormat.encodeToString(value: T): String
    

    您需要enable experimental APIs 才能使用它。

    【讨论】:

    • 您介意提供更多详细信息吗?我将此添加到项目级 build.gradle:tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { kotlinOptions.freeCompilerArgs += ["-Xuse-experimental=org.jetbrains.kotlinx.serialization.ExperimentalSerializationApi"] } 并将 @OptIn(ExperimentalSerializationApi::class) 添加到调用 API 的函数中,但它仍然不起作用。谢谢。
    • 你好,包你能解决这个问题吗?
    【解决方案2】:

    要使用它,您需要导入import kotlinx.serialization.decodeFromString。但是因为这是一个experimental API,所以你还需要用@ExperimentalSerializationApi 标记你的类或方法。但是要启用实验性开关,您还需要通过languageSettings.optIn("kotlin.RequiresOptIn") 添加编译器。

    build.gradle.kts

    plugins {
        kotlin("jvm") version "1.5.31"
        kotlin("plugin.serialization") version "1.5.31"
    }
    
    kotlin.sourceSets.all {
        languageSettings.optIn("kotlin.RequiresOptIn")
    }
    

    test.kts

    import kotlinx.serialization.ExperimentalSerializationApi
    import kotlinx.serialization.SerialFormat
    import kotlinx.serialization.json.Json
    import kotlinx.serialization.decodeFromString
    
    @Serializable
    data class Box(val s: String = "")
    
    @OptIn(ExperimentalSerializationApi::class)
    fun readJson(){
        val deserialized = Json.decodeFromString<Box>("""{"s" : "Hallo"}""")
    }
    

    【讨论】:

    • 就我而言,只需要kotlinx.serialization.json.Jsonkotlinx.serialization.decodeFromString。无需使用@OptIn 或其他两个导入。插件部分是什么:plugins { id 'com.android.application';id 'kotlin-android';id 'kotlinx-serialization' apply true }
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-23
    相关资源
    最近更新 更多