5

我有这段 Scala 代码,它定义了一个排序并将其应用于 TreeSet。这部分编译得很好。

val acctOrdering = new Ordering[Account] {
  def compare(acc1: Account, acc2: Account) {

    // code to compare based on various criteria

  }
}

private var accountSet = new TreeSet[Account]()(acctOrdering)

在代码的其他地方,我想根据我之前的顺序获取集合中的第一个元素(如果第一个元素没有产生我想要的,则稍后获取后续元素,尽管通常没有必要)指定的。我认为以下内容会起作用,但它没有编译:

val firstAccount = accountSet.min

错误是"could not find implicit value for parameter cmp: Ordering[Account]"

但是,如果我在要求最小值时再次指定排序对象,它会编译:

val firstAccount = accountSet.min(acctOrdering)

我认为它会自动使用我在构建时给出的排序,并在我添加到集合时递增排序,所以我不必在调用时再次指定排序min

我究竟做错了什么?我需要在某处显式定义隐式函数吗?

4

1 回答 1

11

发生的事情是您假设min取决于集合的顺序,但事实并非如此。具体来说,min它们max是几乎任何集合上都可用的泛型方法,并且它们采用隐式Ordering参数。

但是,如果您尝试firstKeyand lastKey,它们是SortedSet特定的方法,它们将工作而无需传递任何隐式。

编辑

您可能提出的一个问题是如何确保您的Account类型可以通过任何期望Ordering. Account您可以通过在的对象伴侣中放置一个隐式定义来做到这一点,如下所示:

object Account {
  implicit val ord = new Ordering[Account] {
    def compare(ac1: Account, acc2: Account): Int = {
      // code to compare based on various criteria
    }
  }
}

一旦你这样做了,你就不需要明确地传递排序了。

于 2011-03-27T22:17:17.983 回答