7

我正在从 scala 2.7 切换并订购到 scala 2.8 并使用订购。它看起来很简单,但我想知道我能否让它不那么冗长。例如:

scala> case class A(i: Int)
defined class A
scala> object A extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i}
defined module A

如果我随后尝试创建 TreeMap,则会收到错误消息

scala> new collection.immutable.TreeMap[A, String]()
<console>:10: error: could not find implicit value for parameter ordering: Ordering[A]
       new collection.immutable.TreeMap[A, String]()
       ^

但是,如果我将对象 A 明确指定为排序,则它可以正常工作。

scala> new collection.immutable.TreeMap[A, String]()(A)
res34: scala.collection.immutable.TreeMap[A,String] = Map()

我总是必须明确指定顺序还是有更短的格式?

谢谢

4

3 回答 3

14

请注意,创建一个稍微不那么冗长的方法Ordering

implicit val OrderingA = Ordering.by((_: A).i)

Ordering 的主要优点是您可以为同一类提供许多。如果您的A课程是真的Ordered,那么您应该扩展它。如果没有,您可以显式传递 Ordering,而不是使用隐式:

new collection.immutable.TreeMap[A, String]()(Ordering.by(_.i))
于 2010-04-21T22:54:36.980 回答
11

请注意诊断中的“隐式”一词。声明参数implicit意味着编译器将在您调用构造函数时尝试在范围内找到合适的值。如果您将 Ordering 设为隐式值,则编译器将有资格进行此处理:

scala> implicit object A extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i}
defined module A

scala> val tm1 = new collection.immutable.TreeMap[A, String]()
tm1: scala.collection.immutable.TreeMap[A,String] = Map()

编辑:

该示例在 REPL 中有效,因为 REPL 将您的代码包含在不可见的类定义中。这是一个独立工作的:

case class A(val i:Int) extends Ordered[A] { def compare(o:A) = i - o.i }

object A { implicit object AOrdering extends Ordering[A] { def compare(o1: A, o2: A) = o1.i - o2.i } }

class B {
    import A.AOrdering

    val tm1 = new collection.immutable.TreeMap[A, String]()
}
于 2010-04-21T14:49:31.083 回答
5

Ordering[A]尝试扩展而不是扩展Ordered[A]。像这样:

scala> case class A(val i:Int) extends Ordered[A] {def compare(o:A) = i-o.i}
defined class A

scala> A(1)<A(2)
res0: Boolean = true

scala> A(1)<A(0)
res1: Boolean = false

scala> new collection.immutable.TreeMap[A, String]()
res3: scala.collection.immutable.TreeMap[A,String] = Map()
于 2010-04-21T19:30:49.720 回答