我有一段代码,用于为优先级队列提供隐式排序:
type Time = Int
type Item = (Time, Whatever)
implicit def order(thisItem: Item): Ordered[Item] =
new Ordered[Item] {
override def compare(thatItem: Item) = {
val result = thisItem._1 compareTo thatItem._1
-result
}
}
现在这段代码无法在 Scala 2.7 上编译 - 错误消息是:
error: type mismatch;
found : SimulationMode.this.Time
required: ?{val compareTo: ?}
Note that implicit conversions are not applicable because they are ambiguous:
both method int2Integer in object Predef of type (Int)java.lang.Integer
and method intWrapper in object Predef of type (Int)scala.runtime.RichInt
are possible conversion functions from SimulationMode.this.Time to ?{val compareTo: ?}
val result = thisItem._1 compareTo thatItem._1
^
我找到了两种使其编译的方法 - 要么将 result 的类型声明为 Int,要么将 compareTo 的使用更改为 compare。但我的问题是 - 这种错误是否有原因,该消息是什么意思,这是 scala 编译器中的错误吗? compareTo 只是在 Ordered[A] 特征中调用比较并具有相同的签名...加上它们都返回 Int,那么为什么我自己声明类型很重要?
发生这种情况是因为 Int 没有
compareTo
方法,正如错误所述。此外,当搜索使此工作有效的隐式时,编译器发现转换为 java.lang.Integer
和 scala.runtime.RichInt
之间存在歧义,两者都提供了 compareTo
方法。当您使用 compare
而不是 compareTo
时,它会起作用,因为只有 RichInt
转换提供该方法。仅供参考 compare
来自 scala 的 Ordered
特性。
当你说它在声明结果类型时有效时,我不确定你的意思是什么,这应该没有什么区别,你必须发布你正在使用的代码,这似乎使它工作。
我只想在 Rex 和 Geoff 的答案中添加一个如何处理歧义的实用建议,那就是使用类型归属:
val result = (thisItem._1: Integer) compareTo (thatItem._1: Integer)
无论如何,在这种情况下使用比较可能是最好的解决方案,因为您依赖于 Scala 的类型。
该错误是由 Scala 和 Java 中原始整数装箱不同引起的。 我很难准确说出你的代码在做什么——
thisItem._1
是什么类型? 它是原始整数吗?
无论如何,
compareTo
方法是在java.lang.Integer
和scala.runtime.RichInt
(分别是Java和Scala的装箱整数)上定义的。 比较仅在 scala.runtime.RichInt
上定义。 所以当你使用compare时,它是一个明确的请求;使用 compareTo
,它不知道该使用哪种拳击。