如何重载 Kotlin 的字符串模板运算符美元符号?

问题描述

我确定我已经读过 Kotlin 的字符串模板的“美元运算符”可以重新定义,但是它们的 documentation on operator overloading 没有指示如何重载它,而它们的 documentation on string templates,就像大多数在线关于字符串模板的教程,仅告诉您如何使用美元符号。对 StackOverflow 的搜索同样没有找到解决这个问题的明显问题。

有没有办法重载 Kotlin 字符串模板运算符,也就是美元符号?

举个例子:

data class Point(x: Int,y: Int)
data class Stick(val p: Point,val q: Point)
console.log('${ Stick( Point(2,1),Point(1,7) ) }')

输出

Stick(p=Point(x=2,y=1),q=Point(x=1,y=7))

但我不想那样。我要

[ ( 2,1 ) ; ( 1,7 ) ]

我该怎么做?

解决方法

您不能在字符串模板中重载 $ 运算符。

然而,它只是获取对象或表达式的值;字符串模板通过调用其 toString() 方法将每个对象转换为字符串。每个对象都实现该方法——它在每个对象继承的 Any 类型中定义。 (还有一个 extension method,因此它也适用于 null。)

所以你可以简单地覆盖 toString();每当对象在字符串模板中使用时都会生效 - 以及它被转换为字符串的其他任何地方(例如,如果直接传递给 println() 或记录器)。

在这种情况下,我认为为两个对象提供自己的toString()实现会更灵活,例如:

data class Point(val x: Int,val y: Int) {
    override fun toString() = "( $x,$y )"
}

data class Stick(val p: Point,val q: Point) {
    override fun toString() = "[ $p ; $q ]"
}

提供您自己的 toString() 是使您的对象更普遍有用的一种方法。 data class 为您提供的标准实现清晰易读,但非常冗长,因此提供您自己的实现是很常见的。 (对于not data classes 的类,从 Any 继承的实现非常神秘——例如 Stick@60652518——所以覆盖它更重要!)

一般来说,toString() 倾向于针对程序员(例如显示在日志中)。因此,如果这可能与您想向用户显示的内容不同,那么您可能需要为后者添加一个单独的方法(特别是如果只需要显示部分数据,或者进行更多处理,例如将其转换为用户的语言)。

,

覆盖 Stick 类的 toString() 方法:

data class Stick(val p: Point,val q: Point) {
   override fun toString() = "[ ( ${p.x},${p.y} ) ; ( ${q.x},${q.y} ) ]"
}

我不知道它出现在文档的哪个位置,但我确信我已经看到了。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...