我有一段代码用于为优先级队列提供隐式排序:
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
^
我找到了两种方法来编译 - 要么将 结果 的类型声明为 Int ,要么将 compareTo 的使用更改为 比较 。但我的问题是 - 是否有这样的错误的原因,消息是什么意思,这是scala编译器中的一个错误? compareTo只是在Ordered [A] trait中调用compare并且具有相同的签名...另外它们都返回Int,那么为什么我自己声明类型呢?
答案 0 :(得分:4)
这是因为Int没有compareTo
方法,就像错误所说的那样。此外,当搜索隐式使其工作时,编译器发现转换为java.lang.Integer
和scala.runtime.RichInt
之间存在歧义,两者都提供compareTo
方法。当您使用compare
代替compareTo
时,它可以正常运行,因为只有RichInt
转换才能提供该方法。仅供参考compare
来自scala的Ordered
特征。
当你宣布结果的类型时,我不确定你的意思是什么,这应该没有区别,你必须发布你正在使用的代码,这似乎使它工作
答案 1 :(得分:2)
我想补充Rex和Geoff的答案只有一个实用的建议如何处理歧义是使用类型归属:
val result = (thisItem._1: Integer) compareTo (thatItem._1: Integer)
无论如何,在这种情况下,使用compare可能是最好的解决方案,因为你依赖于Scala的类型。
答案 2 :(得分:1)
错误源于Scala和Java中原始整数的不同装箱。我很难确切地说出你的代码在做什么 - thisItem._1
是什么类型的?它是一个原始整数吗?
无论如何,compareTo
方法同时定义在java.lang.Integer
和scala.runtime.RichInt
上(分别是Java和Scala的盒装整数)。比较仅在scala.runtime.RichInt
上定义。所以当你使用compare时,这是一个明确的请求;使用compareTo
,它不知道要使用哪个拳击。