重载方法调用有替代方案:String.format
Overloaded method call has alternatives: String.format
我在下面编写了以下 Scala 代码来处理我传入的字符串,格式化字符串,将其附加到 StringBuilder
和 return 带有转义 unicode 的格式化 String
返回给我的来电者进行其他处理。
Scala 编译器在 String.format
调用的行中抱怨以下错误:
overloaded method value format with alternatives: (x; java.util.Locale; x: String, X: Object*)
(x:String,x: Object*)
String cannot be applied to (*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
}
}
如何解决这个问题?如何清理代码以实现格式化字符串的目的?提前感谢这里的 Scala 专家
我无法弄清楚到底是什么导致了 "overload clash" 但请注意下面的代码:
scala> "\u%04x\u%04x".format(10,20)
res12: String = \u000a\u0014
使用 StringOps 提供的方法。
String.format
method in Java expects Objects
as its arguments. The Object
type in Java is equivalent to the AnyRef
type in Scala. The primitive types in Scala extend AnyVal
– not AnyRef
. Read more about the differences between AnyVal
, AnyRef
, and Any
in the docs or in this answer。最明显的修复是使用 Java 中的 Integer
包装器 class 来获得 Ints
:
的 Object
表示
String.format("\u%04x\u%04x", new Integer(hi), new Integer(lo))
使用这些包装器 classes 几乎是单一 Scala 代码的象征,并且只应在没有更好的选择时用于与 Java 的互操作性。在 Scala 中更自然的方法是使用 StringOps
等效方法 format
:
"\u%04x\u%04x".format(hi, lo)
您还可以使用 f
interpolator 以获得更简洁的语法:
f"\u$hi%04x\u$lo%04x"
另外,像这里这样使用 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")
}
或者,如果您不必使用 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
我在下面编写了以下 Scala 代码来处理我传入的字符串,格式化字符串,将其附加到 StringBuilder
和 return 带有转义 unicode 的格式化 String
返回给我的来电者进行其他处理。
Scala 编译器在 String.format
调用的行中抱怨以下错误:
overloaded method value format with alternatives:
(x; java.util.Locale; x: String, X: Object*)
(x:String,x: Object*)
String cannot be applied to(*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
}
}
如何解决这个问题?如何清理代码以实现格式化字符串的目的?提前感谢这里的 Scala 专家
我无法弄清楚到底是什么导致了 "overload clash" 但请注意下面的代码:
scala> "\u%04x\u%04x".format(10,20)
res12: String = \u000a\u0014
使用 StringOps 提供的方法。
String.format
method in Java expects Objects
as its arguments. The Object
type in Java is equivalent to the AnyRef
type in Scala. The primitive types in Scala extend AnyVal
– not AnyRef
. Read more about the differences between AnyVal
, AnyRef
, and Any
in the docs or in this answer。最明显的修复是使用 Java 中的 Integer
包装器 class 来获得 Ints
:
Object
表示
String.format("\u%04x\u%04x", new Integer(hi), new Integer(lo))
使用这些包装器 classes 几乎是单一 Scala 代码的象征,并且只应在没有更好的选择时用于与 Java 的互操作性。在 Scala 中更自然的方法是使用 StringOps
等效方法 format
:
"\u%04x\u%04x".format(hi, lo)
您还可以使用 f
interpolator 以获得更简洁的语法:
f"\u$hi%04x\u$lo%04x"
另外,像这里这样使用 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")
}
或者,如果您不必使用 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