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

Kotlin中带可选参数重写toString失效,如何用Kotlin风格解决?

Kotlin数据类重写toString的优雅实现(带可选参数)

我尝试为数据类LatLong实现带可选参数的字符串格式化逻辑,但默认的toString()调用和直接打印对象都没有使用自定义逻辑:

data class LatLong(
    val latitude: Double,
    val longitude: Double
){
    // 编译器不允许用override关键字,因为Any类的toString无参
    fun toString(decimals: Int = 5) = 
        "${"%.${decimals}f".format(latitude)}, ${"%.${decimals}f".format(longitude)}"
}

fun main() {
    println(LatLong(-123.0, 49.0))  // 输出默认数据类格式:LatLong(latitude=-123.0, longitude=49.0)
    println(LatLong(-123.0, 49.0).toString())  // 同上,未调用自定义重载函数
    println(LatLong(-123.0, 49.0).toString(decimals=5))  // 输出预期格式化结果:-123.00000, 49.00000
}

问题核心

  • 自定义的toString(decimals: Int)是重载而非重写,因此无参toString()仍然调用数据类自动生成的版本
  • 直接打印对象会触发无参toString(),所以也不会执行自定义格式化逻辑

符合Kotlin风格的解决方案

方案1:统一默认值,重写无参toString

将默认小数位数定义为类内常量,避免重复定义,同时重写无参toString()调用带参数的版本:

data class LatLong(
    val latitude: Double,
    val longitude: Double
) {
    companion object {
        private const val DEFAULT_DECIMALS = 5
    }

    fun toString(decimals: Int = DEFAULT_DECIMALS): String = 
        "${"%.${decimals}f".format(latitude)}, ${"%.${decimals}f".format(longitude)}"

    override fun toString(): String = toString(DEFAULT_DECIMALS)
}

三种调用方式都会使用自定义逻辑:

  • println(LatLong(-123.0, 49.0)) → 调用重写的无参toString(),使用默认小数位数
  • LatLong(...).toString() → 同上
  • LatLong(...).toString(3) → 调用带参数的重载函数,使用指定小数位数

方案2:使用自定义命名的格式化函数(更推荐)

由于toString()在Kotlin/Java中有明确的无参约定,重载它容易造成混淆。更清晰的方式是自定义格式化函数,再重写无参toString()调用它:

data class LatLong(
    val latitude: Double,
    val longitude: Double
) {
    fun toFormattedString(decimals: Int = 5): String = 
        "${"%.${decimals}f".format(latitude)}, ${"%.${decimals}f".format(longitude)}"

    override fun toString(): String = toFormattedString()
}

这种方式的优势:

  • 函数名toFormattedString明确表达格式化意图,避免重载带来的歧义
  • 保持toString()的语义一致性,同时复用格式化逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 15:10:41