重载方法调用有替代方法:String.format [英] Overloaded method call has alternatives: String.format
问题描述
我在下面编写了以下 Scala 代码来处理我传入的字符串,格式化字符串,将其附加到 StringBuilder
并返回格式化的 String
和转义的 unicode返回给我的来电者进行其他处理.
I wrote the following Scala code below to handle a String that I pass in, format the String, append it to a StringBuilder
and return the formatted String
with escaped unicode back to my caller for other processing.
Scala 编译器在带有以下错误的 String.format
调用的行中抱怨以下内容:
The Scala compiler complains of the following on the lines where there is a String.format
call with the following error:
带有替代方法的重载方法值格式:(x$1; java.util.Locale; x$2: String, X$3: Object*)
(x$1:String,x$2:Object*)
字符串不能应用于 (*String, Int)
overloaded method value format with alternatives:
(x$1; java.util.Locale; x$2: String, X$3: Object*)
(x$1:String,x$2: 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 专家
How do I address this problem? How can I clean up the code to accomplish my purpose of formatting a String? Thanks in advance to the Scala experts here
推荐答案
String.format
方法在 Java 中需要 Objects
作为它的参数.Java 中的 Object
类型等价于 Scala 中的 AnyRef
类型.Scala 中的原始类型扩展了AnyVal
——而不是AnyRef
.详细了解 AnyVal
、AnyRef
和 Any
之间的区别 在文档中 或在 这个答案.最明显的解决方法是使用 Java 中的 Integer
包装器类来获取 Ints
的 Object
表示:
The 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. The most obvious fix is to use the Integer
wrapper class from Java to get an Object
representation of your Ints
:
String.format("\\u%04x\\u%04x", new Integer(hi), new Integer(lo))
使用这些包装器类几乎是单一 Scala 代码的象征,并且只有在没有更好的选择时才应该用于与 Java 的互操作性.在 Scala 中更自然的方法是使用 StringOps
等效方法format
:
Using those wrapper classes is almost emblematic of unidiomatic Scala code, and should only be used for interoperability with Java when there is no better option. The more natural way to do this in Scala would be to either use the StringOps
equivalent method format
:
"\\u%04x\\u%04x".format(hi, lo)
您也可以使用 f
interpolator 更简洁的语法:
You can also use the f
interpolator for a more concise syntax:
f"\\u$hi%04x\\u$lo%04x"
此外,使用像这里这样的 for
循环在 Scala 中是单一的.您最好使用一种功能列表方法,例如 map
、foldLeft
或什至 foreach
以及使用 的部分函数>match
语法.例如,您可以尝试以下操作:
Also, using a for
loop like you have here is unidiomatic in Scala. You're better off using one of the functional list methods like map
, foldLeft
, or even foreach
together with a partial function using the match
syntax. For example, you might try something like:
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 替换整个方法体代码>:
Or, if you don't have to use StringBuilder
, which really only needs to be used in cases where you are appending many strings, you can replace your whole method body with 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
:
Or a even map
followed by a 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
这篇关于重载方法调用有替代方法:String.format的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!