如何在此Scala代码中与compareTo进行比较?

时间:2010-01-28 14:07:26

标签: compiler-construction scala

我有一段代码用于为优先级队列提供隐式排序:

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,那么为什么我自己声明类型呢?

3 个答案:

答案 0 :(得分:4)

这是因为Int没有compareTo方法,就像错误所说的那样。此外,当搜索隐式使其工作时,编译器发现转换为java.lang.Integerscala.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.Integerscala.runtime.RichInt上(分别是Java和Scala的盒装整数)。比较仅在scala.runtime.RichInt上定义。所以当你使用compare时,这是一个明确的请求;使用compareTo,它不知道要使用哪个拳击。