我试图指定所有AbstractTaskKey都是有序的,无论它们属于哪个AbstractTaskKeys容器。
如下面的代码所示,很容易为每个特定的外部类指定一个顺序,但这意味着在每个不同的地方我想要排序allKeys我需要使用sortBy(或定义一个隐含的ord这是专门针对范围内的任何外外类。
我希望能够为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)
答案 0 :(得分:0)
关键是将隐式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
}
这不允许您比较AbstractTaskKey
的不同封闭实例中AbstractTaskKeys
的实例,但这似乎并不是您正在寻找的内容。如果是,您可以使用路径相关类型Ordering
定义AbstractTaskKeys#AbstractTaskKey
:
implicit val ord: Ordering[AbstractTaskKeys#AbstractTaskKey] = Ordering.by(_.id)