use*_*558 6 string unicode stringbuilder scala
我在下面编写了下面的Scala代码来处理我传入的String,格式化String,将其附加到a StringBuilder并将String带有转义的unicode 的格式化返回给我的调用者以进行其他处理.
Scala编译器在存在String.format以下错误的调用行时抱怨以下内容:
带备选方法的重载方法值格式:
(x$1; java.util.Locale; x$2: String, X$3: Object*)(x$1:String,x$2: Object*)无法应用字符串(*String, Int)
class TestClass {
private def escapeUnicodeStuff(input: String): String = {
//type StringBuilder = scala.collection.mutable.StringBuilder
val sb = new StringBuilder()
val cPtArray = toCodePointArray(input) //this method call returns an Array[Int]
val len = cPtArray.length
for (i <- 0 until len) {
if (cPtArray(i) > 65535) {
val hi = (cPtArray(i) - 0x10000) / 0x400 + 0xD800
val lo = (cPtArray(i) - 0x10000) % 0x400 + 0xDC00
sb.append(String.format("\\u%04x\\u%04x", hi, lo)) //**complains here**
} else if (codePointArray(i) > 127) {
sb.append(String.format("\\u%04x", codePointArray(i))) //**complains here**
} else {
sb.append(String.format("%c", codePointArray(i))) //**complains here**
}
}
sb.toString
}
}
Run Code Online (Sandbox Code Playgroud)
我该如何解决这个问题?如何清理代码以实现格式化String的目的?在此感谢Scala专家
Ben*_*ich 12
String.formatJava中的方法需要Objects作为其参数.将Object在Java类型等同于AnyRef在斯卡拉类型.Scala中的原始类型扩展AnyVal- 不是AnyRef.了解更多关于的差异之间AnyVal,AnyRef以及Any 在文档或这个答案.最明显的解决方法是使用IntegerJava中的包装器类来Object表示您的Ints:
String.format("\\u%04x\\u%04x", new Integer(hi), new Integer(lo))
Run Code Online (Sandbox Code Playgroud)
使用这些包装类几乎是单一的Scala代码的象征,并且只有在没有更好的选择时才应该用于与Java的互操作性.在Scala中执行此操作的更自然的方法是使用StringOps等效方法format:
"\\u%04x\\u%04x".format(hi, lo)
Run Code Online (Sandbox Code Playgroud)
您还可以使用f插值器来获得更简洁的语法:
f"\\u$hi%04x\\u$lo%04x"
Run Code Online (Sandbox Code Playgroud)
此外,使用for像你在这里的循环在Scala中是单一的.你最好不要使用的功能列表的方法,如一个map,foldLeft或者甚至foreach连同使用部分功能match语法.例如,您可以尝试以下方法:
toCodePointArray(input).foreach {
case x if x > 65535 =>
val hi = (x - 0x10000) / 0x400 + 0xD800
val lo = (x - 0x10000) % 0x400 + 0xDC00
sb.append(f"\\u$hi%04x\\u$lo%04x")
case x if > 127 => sb.append(f"\\u$x%04x")
case x => sb.append(f"$x%c")
}
Run Code Online (Sandbox Code Playgroud)
或者,如果您不必使用StringBuilder,实际上只需要在附加许多字符串的情况下使用,您可以用以下内容替换整个方法体foldLeft:
def escapeUnicodeStuff(input: String) = toCodePointArray(input).foldLeft("") {
case (acc, x) if x > 65535 =>
val hi = (x - 0x10000) / 0x400 + 0xD800
val lo = (x - 0x10000) % 0x400 + 0xDC00
acc + f"\\u$hi%04x\\u$lo%04x"
case (acc, x) if x > 127 => acc + f"\\u$x%04x"
case (acc, x) => acc + f"$x%c"
}
Run Code Online (Sandbox Code Playgroud)
或者偶然map后跟一个mkString:
def escapeUnicodeStuff(input: String) = toCodePointArray(input).map {
case x if x > 65535 =>
val hi = (x - 0x10000) / 0x400 + 0xD800
val lo = (x - 0x10000) % 0x400 + 0xDC00
f"\\u$hi%04x\\u$lo%04x"
case x if x > 127 => f"\\u$x%04x"
case x => f"$x%c"
}.mkString
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2630 次 |
| 最近记录: |