我在下面写了下面的Scala代码来处理我传入的String,格式化String,将其附加到StringBuilder
并将带有转义unicode的格式化String
返回给我的调用者处理
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
}
}
如何解决此问题?如何清理代码以实现格式化String的目的?在此先感谢Scala专家
答案 0 :(得分:9)
Java中的String.format
方法期望Objects
作为其参数。 Java中的Object
类型等同于Scala中的AnyRef
类型。 Scala中的原始类型扩展AnyVal
- 而不是AnyRef
。详细了解AnyVal
,AnyRef
和Any
in the docs或this answer之间的差异。最明显的解决方法是使用Java中的Integer
包装器类来获取Object
的{{1}}表示形式:
Ints
使用这些包装类几乎是单一Scala代码的象征,只有当没有更好的选择时才应该用于与Java的互操作性。 Scala中更自然的方法是使用StringOps
等效方法String.format("\\u%04x\\u%04x", new Integer(hi), new Integer(lo))
:
format
您还可以使用f
interpolator获得更简洁的语法:
"\\u%04x\\u%04x".format(hi, lo)
此外,使用像这里一样的f"\\u$hi%04x\\u$lo%04x"
循环在Scala中是非常不同的。您最好使用for
,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")
}
,只需要在附加许多字符串的情况下使用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"
}
或偶数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
答案 1 :(得分:1)
我无法弄清楚究竟是什么造成了这种&#34;超载冲突&#34;但请注意以下代码:
scala> "\\u%04x\\u%04x".format(10,20)
res12: String = \u000a\u0014
使用StringOps提供的工作。