scala - String 上的重载加 `+` 运算符
问题描述
在下面的示例中,我试图声明一个类WrappedString
,它只是包装了一个String
[1]。我希望能够将此类实例与+
运算符连接起来,并在必要时将普通String
实例自动转换为WrappedString
实例。
因此,运算符有三种可能的应用程序+
应该返回一个实例,示例底部的WrappedString
调用说明了这一点。println()
import scala.language.implicitConversions
object test extends App {
case class WrappedString(value: String) {
override def toString = s"[$value]"
def +(right: WrappedString) = WrappedString(value + right.value)
}
object WrappedString {
implicit def fromString(value: String) = WrappedString(value)
}
implicit class StringExtensions(value: String) {
// Isn't actually used in the code below.
def +(right: WrappedString) = WrappedString(value) + right
}
println(WrappedString("a") + WrappedString("b")) // [ab]
println(WrappedString("a") + "b") // [ab]
// Would like this to print `[ab]`
println("a" + WrappedString("b")) // a[b]
}
出于某种原因,第三个示例打印a[b]
. 在与字符串连接以产生最终结果之前,该WrappedString
实例被转换为 a 。String
"a"
如何更改WrappedString
和/或隐含的声明,以便在第三个示例中,在应用运算符之前将其String
转换为 a ?WrappedString
+
[1]:在我正在处理的项目中,包装后的字符串以ANSI SGR 转义码的形式携带格式信息。
解决方案
编译器永远不会选择隐式+
方法而不是显式+
方法,这是String
类所拥有的,所以"a" + WrappedString("b")
总是会变成"a".+(WrappedString("b").toString)
.
要强制转换,您可以选择一个不同的方法名称,一个String
没有的方法名称,以及一个隐式类,这意味着它不能是一个case
类。这样你就不需要implicitConversions
导入,这是不鼓励的。
implicit class WrappedString(val value: String) {
override def toString = s"[$value]"
def +#(right: WrappedString) = WrappedString(value + right.value)
}
WrappedString("a") +# WrappedString("b") // [ab]
WrappedString("a") +# "b" // [ab]
"a" +# WrappedString("b") // [ab]
"a" +# "b" // also [ab]
如果您不使用标准库中已经存在的类名,这也可能会有所帮助。
推荐阅读
- file-upload - Vimeo API:使用可恢复方式上传视频文件
- visual-studio-code - 更改快速选择器的悬停颜色
- regex - 如何使用 RegEx 捕获 VBA (Outlook) 中特定字符串之后的下一行?
- java - 如何在 Firestore 中使用 POJO 更新所有文档中的一个字段?
- c++ - Arduino - 关于数据类型
- reactjs - 以 Dropdown 作为标签输入,溢出屏幕。如何让它响应?
- php - Slim 应用程序错误(发生网站错误)
- java - 一次最大 Spring "@Async" 调用数
- android - 如何使用 Cordova 本机更改 Android 导航栏颜色?
- angular - 如何使用angular2选择特定行进行删除操作