重载方法调用有替代方法:String.format [英] Overloaded method call has alternatives: String.format

查看:107
本文介绍了重载方法调用有替代方法: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.详细了解 AnyValAnyRefAny 之间的区别 在文档中 或在 这个答案.最明显的解决方法是使用 Java 中的 Integer 包装器类来获取 IntsObject 表示:

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 中是单一的.您最好使用一种功能列表方法,例如 mapfoldLeft 或什至 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆