Scala 2.9.2 无法处理 String 类的重载格式方法 - 为什么



示例:

scala> String.format("%d", 2)
<console>:8: error: overloaded method value format with alternatives:
  (java.util.Locale,java.lang.String,<repeated...>[java.lang.Object])java.lang.String <and>
  (java.lang.String,<repeated...>[java.lang.Object])java.lang.String
 cannot be applied to (java.lang.String, Int)
              String.format("%d", 2)
                     ^

为什么 Scala 不能处理 String 类的重载format方法?

使用:Windows 7 64 位上的 Scala 2.9.2。

请改用这个:

"%d".format(2)

String.format 方法是一个 Java 的东西,所以它需要输入参数是 java.lang.Object 的子类型。 Scala的Int不是java.lang.Object

scala> val i: java.lang.Object = 2
<console>:7: error: type mismatch;
 found   : Int(2)
 required: java.lang.Object
Note: an implicit exists from scala.Int => java.lang.Integer, but
methods inherited from Object are rendered ambiguous.  This is to avoid
a blanket implicit which would convert any scala.Int to any AnyRef.
You may wish to use a type ascription: `x: java.lang.Integer`.
       val i: java.lang.Object = 2
                                 ^

要了解更多信息,您应该阅读 Scala 对 AnyValAnyRef类型的区别。 Java在效率方面区分了对象(如Integer)和原语(如int)。 Scala也有类似的区别。 所有类型都从Any扩展,但"值类型"(基本上对应于基元)从AnyVal扩展,其他所有内容都从AnyRef扩展(基本上是java.lang.Object)。 在此处阅读更多内容。

因此,要使用String.format,您必须将其替换为Java Integer,这是一个Object

String.format("%d", new java.lang.Integer(2))

但不要这样做;只需以Scala的方式使用它,如上所述。

第一个重载定义无法匹配,因为第一个参数是 Locale ,而您提供了一个 String。

第二个

备选方案无法匹配,因为第二个参数是 Object 的 vararg 参数,但您提供了IntInt不是Object的子类型(在Scala中称为AnyRef)。Java通过自动装箱"修复"它,但在Scala类型系统中,没有从原始类型Intjava.lang.Integer的自动转换。

如果 Java 定义是泛型的,比如 format[T](f: String, args: T*) ,Scala 将允许你调用,因为 Scala 中的无界类型参数也超过了基元类型。

最新更新