此 Scala 代码中的compare 与compareTo 有何不同?

问题描述 投票:0回答:3

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

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

scala
3个回答
5
投票

发生这种情况是因为 Int 没有

compareTo
方法,正如错误所述。此外,当搜索使此工作有效的隐式时,编译器发现转换为
java.lang.Integer
scala.runtime.RichInt
之间存在歧义,两者都提供了
compareTo
方法。当您使用
compare
而不是
compareTo
时,它会起作用,因为只有
RichInt
转换提供该方法。仅供参考
compare
来自 scala 的
Ordered
特性。

当你说它在声明结果类型时有效时,我不确定你的意思是什么,这应该没有什么区别,你必须发布你正在使用的代码,这似乎使它工作。


2
投票

我只想在 Rex 和 Geoff 的答案中添加一个如何处理歧义的实用建议,那就是使用类型归属:

val result = (thisItem._1: Integer) compareTo (thatItem._1: Integer)

无论如何,在这种情况下使用比较可能是最好的解决方案,因为您依赖于 Scala 的类型。


1
投票

该错误是由 Scala 和 Java 中原始整数装箱不同引起的。 我很难准确说出你的代码在做什么——

thisItem._1
是什么类型? 它是原始整数吗?

无论如何,

compareTo
方法是在
java.lang.Integer
scala.runtime.RichInt
(分别是Java和Scala的装箱整数)上定义的。 比较仅在
scala.runtime.RichInt
上定义。 所以当你使用compare时,它是一个明确的请求;使用
compareTo
,它不知道该使用哪种拳击。

© www.soinside.com 2019 - 2024. All rights reserved.