我有这段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时不必再次指定顺序。

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

最佳答案

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

但是,如果您尝试使用firstKeylastKey,它们是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
    }
  }
}

完成此操作后,您将无需显式传递订单。

10-06 12:35
查看更多