我在抽象类中有一个泛型T列表。
abstract class MyAbstractClass[T] {
type SortOrder
def getSorterFunc(): T => SortOrder
def sort(myList: List[T]) = {
val sortFunc = getSorterFunc()
myList.sortBy(sortFunc)
}
}
object SampleObject extends MyAbstractClass[(String,Int,List[Int])] {
type SortOrder = (String,Int)
override def getSorterFunc(): (String,Int,List[Int]) => SortOrder {
val sortFunc : (String,Int,List[Int]) => SortOrder = {
case (username, id, addresses) => (username, id)
}
sortFunc
}
}
抽象类中可以有许多派生类。 我想在列表[T]上进行自定义排序。怎么做到这一点? 上面的代码抛出了编译错误。
No implicit Ordering defined for MyAbstractClass.this.SortOrder.
答案 0 :(得分:3)
不幸的是,您无法使用抽象类型实现此目的。要制作依赖于隐式参数compile的通用代码,您需要一个上下文绑定,并且上下文边界只能作为类型参数传递。
在这里,我将您的抽象类型移动到一个类型参数中并添加了一个上下文绑定(注意构造函数中传递的隐式参数):
abstract class MyAbstractClass[T, SortOrder](implicit ord: Ordering[SortOrder]) {
def getSorterFunc(): (T) => SortOrder
def sort(myList: List[T]) = {
val sortFunc = getSorterFunc()
myList.sortBy(sortFunc)
}
}
object SampleObject extends MyAbstractClass[(String, Int, List[Int]), (String, Int)] {
def getSorterFunc() = {
case (username, id, addresses) => (username, id)
}
}
这样编译器事先知道MyAbstractClass
的任何子类都有来定义它的SortOrder
,以便有一种方法可以按它排序。
答案 1 :(得分:0)
你可以添加缺失的隐含:它也可以是抽象的。
abstract class MyAbstractClass[T] {
type SortOrder
implicit val ordering: Ordering[SortOrder]
def getSorterFunc(): T => SortOrder
def sort(myList: List[T]) = {
val sortFunc = getSorterFunc()
myList.sortBy(sortFunc)
}
}
当然,这种方法的问题在于使用它最终会比谢尔盖的回答更加丑陋:
object SampleObject extends MyAbstractClass[(String, Int, List[Int])] {
type SortOrder = (String, Int)
val ordering = implicitly[Ordering[(String, Int)]]
override def getSorterFunc() = {
val sortFunc: ((String, Int, List[Int])) => SortOrder = {
case (username, id, addresses) => (username, id)
}
sortFunc
}
}
另外,如果你写implicit val ordering = implicitly[Ordering[(String, Int)]]
,你将进入一个无限循环,需要手动建立排序。