String 如何使Kotlin';s字符串模板运算符(美元符号)?
我相信我已经读过Kotlin的字符串模板“美元运算符”可以重新定义,但它们并没有说明如何重载它,而且它们与大多数关于字符串模板的在线教程一样,只告诉您如何使用美元符号。对StackOverflow的搜索同样没有发现任何明显的问题来解决这个问题 有没有办法重载Kotlin字符串模板操作符,也就是美元符号 例如:String 如何使Kotlin';s字符串模板运算符(美元符号)?,string,kotlin,operator-overloading,dollar-sign,String,Kotlin,Operator Overloading,Dollar Sign,我相信我已经读过Kotlin的字符串模板“美元运算符”可以重新定义,但它们并没有说明如何重载它,而且它们与大多数关于字符串模板的在线教程一样,只告诉您如何使用美元符号。对StackOverflow的搜索同样没有发现任何明显的问题来解决这个问题 有没有办法重载Kotlin字符串模板操作符,也就是美元符号 例如: data class Point(x: Int, y: Int) data class Stick(val p: Point, val q: Point) console.log('${
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 ) ]
我该怎么做呢?重写
Stick
类的toString()
方法:
data class Stick(val p: Point, val q: Point) {
override fun toString() = "[ ( ${p.x} , ${p.y} ) ; ( ${q.x} , ${q.y} ) ]"
}
我不知道它出现在文档中的什么地方,但我肯定我已经看过了。覆盖
粘贴类的toString()
方法:
data class Stick(val p: Point, val q: Point) {
override fun toString() = "[ ( ${p.x} , ${p.y} ) ; ( ${q.x} , ${q.y} ) ]"
}
我不知道它出现在文档中的什么地方,但我肯定我已经看过了。在字符串模板中不能重载$
运算符
但是,它只获取对象或表达式的值;字符串模板通过调用每个对象的方法将其转换为字符串。 每个对象都实现该方法——它是在每个对象继承的类型中定义的。 (还有一个so,它也适用于null
)
因此,您可以简单地重写toString()
;这将在对象在字符串模板中使用时生效,并且在其他任何地方它都会转换为字符串(例如,如果直接传递给或传递给记录器)
在这种情况下,我认为为两个对象提供自己的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()
是使对象更普遍有用的一种方法。 数据类
提供的标准实现清晰易读,但相当冗长,因此提供自己的实现是很常见的。 (对于不是数据类的类
es,从Any
继承的实现非常神秘-例如Stick@60652518
-因此覆盖它更为重要!)
一般来说,toString()
倾向于针对程序员(例如,在日志中显示)。 因此,如果这可能不同于您希望向用户显示的内容,那么您可能需要为后者添加一个单独的方法(特别是如果只需要显示部分数据,或者需要进行更多处理,例如将其翻译为用户的语言)。您不能在字符串模板中重载$
运算符
但是,它只获取对象或表达式的值;字符串模板通过调用每个对象的方法将其转换为字符串。 每个对象都实现该方法——它是在每个对象继承的类型中定义的。 (还有一个so,它也适用于null
)
因此,您可以简单地重写toString()
;这将在对象在字符串模板中使用时生效,并且在其他任何地方它都会转换为字符串(例如,如果直接传递给或传递给记录器)
在这种情况下,我认为为两个对象提供自己的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()
是使对象更普遍有用的一种方法。 数据类
提供的标准实现清晰易读,但相当冗长,因此提供自己的实现是很常见的。 (对于不是数据类的类
es,从Any
继承的实现非常神秘-例如Stick@60652518
-因此覆盖它更为重要!)
一般来说,toString()
倾向于针对程序员(例如,在日志中显示)。 因此,如果这可能与您希望向用户显示的内容不同,那么您可能需要为后者添加一个单独的方法(特别是如果只需要显示部分数据,或者需要进行更多处理,例如将其翻译为用户语言)。我从未见过有任何说法说您可以覆盖$
“运算符”。它只需对传递给它的任何内容调用toString
。您可以在特定类上重写toString
,但是没有任何机制可以将$
更改为除了在字符串模板中调用toString
之外的其他操作。我不遵循此参数。这不是说你不能覆盖+
操作符吗;它只需对传递给它的任何内容调用plus
,并且除了调用plus
之外,没有任何机制可以更改+
来执行其他操作。我从来没有这样想过,因为我没有把toString
看作一个操作符,因为它不是Java语言。但是当你这样说的时候,它看起来和其他操作符是一样的。@Tenfour04看到了所选的答案,这对于为什么$
不是操作符来说是一个很好的论据。我从来没有看到过任何东西说你可以覆盖$
操作符。它只需对传递给它的任何内容调用toString
。您可以在特定类上重写toString
,但是没有任何机制可以将$
更改为除了在字符串模板中调用toString
之外的其他操作。我不遵循此参数。这不是说你不能覆盖+
操作符吗;它只需对传递给它的任何内容调用plus
,并且除了调用plus
之外,没有任何机制可以更改+
来执行其他操作。我从来没有这样想过,因为我没有把toString
看作一个操作符,因为它不是Java语言。但是当你这样说的时候,它看起来和其他操作符是一样的。@Tenfour04看到了选择的答案,这是一个非常好的答案