我试图用一个具有可选参数的自定义toString
来覆盖数据类的toString
函数,但它没有按预期工作:
data class LatLong(
val latitude: Double,
val longitude: Double
){
// Override keyword not allowed by compiler here
fun toString(decimals: Int = 5) =
"${"%.${decimals}f".format(latitude)}, ${"%.${decimals}f".format(longitude)}"
}
fun main() {
println(LatLong(-123.0, 49.0)) // prints: "LatLong(latitude=-123.0, longitude=49.0)" i.e. does not call custom toString
println(LatLong(-123.0, 49.0).toString()) // prints: "LatLong(latitude=-123.0, longitude=49.0)" i.e. does not call custom toString
println(LatLong(-123.0, 49.0).toString(decimals=5)) // prints: "-123.00000, 49.00000"
}
问题是,我应该如何覆盖它,以获得您所期望的行为(即,上面的所有3个调用都应该使用自定义方法)?
我当然可以加上
override fun toString() = toString(decimals=5)
但这意味着要定义两次default参数,这会导致将来的bug。当然,我可以将default定义为常量和toString
a的引用,但这看起来很混乱。令人惊讶的是LatLong(...).toString()
没有调用新方法。
什么是“Kotlinic”方式来处理这个问题?
1条答案
按热度按时间1tu0hz3e1#
你不需要声明两次默认值,只需在
toString
覆盖中声明它,而不是在你自己的toString
参数列表中声明:当然,如果您有更多的格式选项,这会变得有点复杂,但您总是可以将所有内容 Package 在一个(数据)类中,并以一个参数结束。
顺便说一下,调用
toString()
的参数列表 * 完全 * 匹配数据类自动声明的无参数toString
重载。另一方面,如果考虑可选参数,它只匹配您声明的重载。因此编译器有很好的理由更倾向于将LatLong(...).toString()
解析为无参数toString
方法,而不是您声明的方法。