You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin序列化时将Float类型speed字段保留三位小数?

解决方案

Kotlinx Serialization 本身没有提供直接的格式化注解来控制浮点数字的小数位数,要实现speed字段保留三位小数、distance字段保持原样的需求,你需要自定义序列化器,并通过@Serializable(with = ...)注解指定给speed字段。

步骤1:自定义浮点数字序列化器

创建一个专门处理三位小数格式化的序列化器,同时兼容可空类型:

import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

object ThreeDecimalsFloatSerializer : KSerializer<Float?> {
    override val descriptor: SerialDescriptor = 
        PrimitiveSerialDescriptor("ThreeDecimalsFloat", PrimitiveKind.FLOAT)

    override fun serialize(encoder: Encoder, value: Float?) {
        // 将浮点值四舍五入到三位小数
        val roundedValue = value?.let {
            Math.round(it * 1000) / 1000.0F
        } ?: 0F
        encoder.encodeFloat(roundedValue)
    }

    override fun deserialize(decoder: Decoder): Float? {
        // 反序列化保持默认逻辑,直接解析浮点值
        return decoder.decodeNullableFloat()
    }
}

如果需要在JSON中把speed显示为带三位小数的字符串(比如"speed": "51.130"),可以修改序列化器的serialize方法:

override fun serialize(encoder: Encoder, value: Float?) {
    val formattedString = value?.let { String.format("%.3f", it) } ?: "0.000"
    encoder.encodeString(formattedString)
}

步骤2:给speed字段绑定自定义序列化器

修改Event数据类,在speed字段上添加@Serializable(with = ...)注解:

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonElement

@Serializable
data class Event(
    @SerialName("name")
    val name: String? = "",
    @SerialName("speed")
    @Serializable(with = ThreeDecimalsFloatSerializer::class)
    val speed: Float? = 0F,
    @SerialName("distance")
    val distance: Float? = 0F,
)

步骤3:测试序列化效果

使用你原来的序列化代码测试:

fun main() {
    val event = Event(speed = 51.129789f, distance = 123.456789f)
    val json = Json { encodeDefaults = true }
    val jsonString = json.encodeToString(event)
    println(jsonString)
}

输出示例(数值型格式化):

{"name":"","speed":51.13,"distance":123.456787}

如果用字符串型格式化,输出会是:

{"name":"","speed":"51.130","distance":123.456787}

关键说明

  • 自定义序列化器可以精准控制单个字段的序列化逻辑,不会影响其他字段(比如distance保持默认序列化行为)。
  • 四舍五入逻辑通过Math.round(it * 1000) / 1000.0F实现,确保保留三位小数。

内容的提问来源于stack exchange,提问作者user1443721

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 05:58:35