Scala 2.8 TreeMap и пользовательский порядок - PullRequest
6 голосов
/ 21 апреля 2010

Я переключаюсь с 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()

Всегда ли нужно явно указывать порядок или есть более короткий формат?

Спасибо

Ответы [ 3 ]

13 голосов
/ 22 апреля 2010

Имейте в виду, есть немного менее многословный способ создания Ordering:

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

Основным преимуществом заказа является то, что вы можете предоставить множество из них для одного и того же класса. Если ваш A класс действительно Ordered, то вам просто нужно его расширить. Если нет, то вместо использования имплицитов вы можете явно передать Заказ:

new collection.immutable.TreeMap[A, String]()(Ordering.by(_.i))
10 голосов
/ 21 апреля 2010

Обратите внимание на слово «неявный» в диагностике. Параметр объявлен 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()

Edit:

Этот пример работает в 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]()
}
5 голосов
/ 21 апреля 2010

Вместо расширения 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()
...