【问题标题】:Defining an Ordered instance for an Inner class independently from Outer class instance独立于 Outer 类实例为 Inner 类定义 Ordered 实例
【发布时间】:2015-09-03 17:08:03
【问题描述】:

我试图指定所有 AbstractTaskKey 都是有序的,无论它们属于哪个 AbstractTaskKeys 容器。

如下面的代码所示,为每个特定的外部类指定排序很容易,但这意味着在每个不同的地方我想对所有需要使用 sortBy 的键进行排序(或定义一个隐含的特定于任何一个的排序)范围内的子外部类)。

我希望能够为 AbstractTaskKey 定义一个 Ordered 实例,该实例适用于 AbstractTaskKeys 的所有子类。

我尝试按照其他 SO 帖子的建议在一堆不同的地方添加各种差异注释、子类和通配符,但无济于事。

如何使我的 AbstractTaskKey 的 Ordered 实例(或 Ordering)通用?

object HelloWorld {
  def main(args: Array[String]) {
    val someTaskKeyConsumer = new SomeTaskKeyConsumer[FooTaskKeys](FooTaskKeys)
    println(someTaskKeyConsumer.sortedKeysLength)
  }
}

trait AbstractTaskKeys {
  // Tried: traitAbstractTaskKey extends Ordered[...] too
  trait AbstractTaskKey {val id: Int}

  // Really I want _#AbstractTaskKey or (_ <: AbstractTaskKeys)#AbstractTaskKey
  implicit val ord: Ordering[AbstractTaskKey] = Ordering.by(_.id)
  val allKeys: List[AbstractTaskKey]
}

class SomeTaskKeyConsumer[TaskKeys <: AbstractTaskKeys](taskKeys: TaskKeys) {
  def sortedKeysLength: Int
    // No implicit Ordering defined for SomeTaskKeyConsumer.this.taskKeys.AbstractTaskKey
    //= taskKeys.allKeys.sorted.length     
    = taskKeys.allKeys.sortBy(_.id).length // works fine
}

trait FooTaskKeys extends AbstractTaskKeys
object FooTaskKeys extends FooTaskKeys {
  case object FooTask0 extends AbstractTaskKey {val id = 0}
  val allKeys = List(FooTask0)

【问题讨论】:

    标签: scala inner-classes traits


    【解决方案1】:

    关键是将您的隐式 Ordering 放在 AbstractTaskKey 的伴随对象中,以便它在编译器需要填充隐式时将搜索的范围内。

    trait AbstractTaskKeys {
      trait AbstractTaskKey {val id: Int}
      object AbstractTaskKey {
        implicit val ord: Ordering[AbstractTaskKey] = Ordering.by(_.id)
      }
      val allKeys: List[AbstractTaskKey]
    }
    
    class SomeTaskKeyConsumer[TaskKeys <: AbstractTaskKeys](taskKeys: TaskKeys) {
      def sortedKeysLength: Int = taskKeys.allKeys.sorted.length
    }
    

    这将不允许您从 AbstractTaskKeys 的不同封闭实例中比较 AbstractTaskKey 的实例,但这似乎不是您想要的。如果是,您可以定义一个Ordering,其路径依赖类型为AbstractTaskKeys#AbstractTaskKey

    implicit val ord: Ordering[AbstractTaskKeys#AbstractTaskKey] = Ordering.by(_.id)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-30
      • 1970-01-01
      • 2018-06-12
      • 1970-01-01
      相关资源
      最近更新 更多