1

例子:

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不能处理类的重载format方法String

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

4

2 回答 2

15

改用这个:

"%d".format(2)

String.format方法是 Java 的东西,所以它期望输入参数是java.lang.Object. 斯卡拉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 区分了对象(like Integer)和基元(like int)。Scala 也有类似的区别。所有类型都扩展自Any,但“值类型”(基本上对应于原语)扩展自AnyVal,其他一切都扩展自AnyRef(基本上java.lang.Object)。在这里阅读更多。

所以,要使用String.format你必须用 Java 替换它Integer,这是一个Object

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

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

于 2012-09-16T17:15:52.287 回答
2

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

第二种选择无法匹配,因为第二个参数是 的 vararg 参数Object,但您提供了Int. Int不是(在 Scala中Object调用)的子类型。AnyRefJava 通过自动装箱“修复”它,但在 Scala 类型系统中没有从原始类型自动转换Intjava.lang.Integer.

如果 Java 定义是通用的,比如format[T](f: String, args: T*),Scala 将允许您调用,因为 Scala 中的无界类型参数也涵盖原始类型。

于 2012-09-16T18:33:04.910 回答