Scala 2.8 TreeMap 和自定义排序

发布于 2024-08-29 08:37:21 字数 742 浏览 13 评论 0原文

我正在从 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()

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

谢谢

I'm switching from scala 2.7 and ordered to scala 2.8 and using ordering. It looks quite straight forward but I was wondering could I make it a little less verbose. For example:

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

If I then try to create a TreeMap I get an error

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]()
       ^

However if I explicitly specify the object A as the ordering it works fine.

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

Do I always have to explicitly specify the ordering or is there a shorter format?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

猫九 2024-09-05 08:37:21

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

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

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

new collection.immutable.TreeMap[A, String]()(Ordering.by(_.i))

Mind you, there's a slightly less verbose way of creating an Ordering:

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

The main advantage of Ordering being you can provide many of them for the same class. If your A class is truly Ordered, then you should just extend that. If not, instead of using implicits, you may pass an Ordering explicitly:

new collection.immutable.TreeMap[A, String]()(Ordering.by(_.i))
杯别 2024-09-05 08:37:21

请注意诊断中的“隐式”一词。该参数被声明为隐式,这意味着编译器将在您调用构造函数时尝试在范围内找到合适的值。如果您将 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]()
}

Notice the word "implicit" in the diagnostic. The parameter is declared implicit meaning the compiler will try to find a suitable value in scope at the point you invoke the constructor. If you make your Ordering an implicit value, it will be eligible for this treatment by the compiler:

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:

That example works in the REPL because the REPL encloses your code in invisible class definitions. Here's one that works free-standing:

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]()
}
夜夜流光相皎洁 2024-09-05 08:37:21

不要扩展 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()

Instead of extending Ordering[A], try extending Ordered[A]. Like so:

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文