重载方法调用有替代方法:String.format

时间:2015-04-26 19:29:50

标签: string scala unicode stringbuilder

我在下面写了下面的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专家

2 个答案:

答案 0 :(得分:9)

Java中的String.format方法期望Objects作为其参数。 Java中的Object类型等同于Scala中的AnyRef类型。 Scala中的原始类型扩展AnyVal - 而不是AnyRef。详细了解AnyValAnyRefAny in the docsthis 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中是非常不同的。您最好使用formap甚至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提供的工作。