代码之家  ›  专栏  ›  技术社区  ›  David

Scala 2.8树映射和自定义排序

  •  6
  • David  · 技术社区  · 16 年前

    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
    

    如果我尝试创建一个树映射,我会得到一个错误

    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 回复  |  直到 16 年前
        1
  •  11
  •   Randall Schulz    16 年前

    注意诊断中的“隐式”一词。参数已声明 implicit 这意味着编译器将尝试在调用构造函数时在作用域中找到合适的值。如果将排序设置为隐式值,则编译器可以对其进行此处理:

    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]()
    }
    
        2
  •  13
  •   Daniel C. Sobral    16 年前

    Ordering :

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

    订购的主要优点是,您可以为同一类提供许多。如果你的 A 课堂是真正的 Ordered

    new collection.immutable.TreeMap[A, String]()(Ordering.by(_.i))
    
        3
  •  5
  •   Elazar Leibovich    16 年前

    而不是延伸 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()