假设我有:
object test{
abstract class Base
然后是扩展 Base 的两个案例类 alpha 和 beta,这样写:
case class alpha(num: Int, other: String) extends Base
case class beta(num:Int, other_two: String) extends Base
然后假设我有一个基本对象列表,List[Base]
.
其中一些对象是 alpha,有些是 beta。我想按字段num
(alpha 和 beta 对象之间的公共字段)对它们进行排序。
根据我阅读/谷歌搜索的内容,每个人和他们的祖母建议执行以下操作:
val i: List[Base] = List(alpha(4,"test"),beta(2,"test_two")).sortby(_.num)
但是,这不起作用。 工作原理是:
val j: List[Base] =List(alpha(4,"test"),beta(2,"test_two")).sortWith(num(_) < num(_))
}
我的问题是为什么前者不起作用,为什么后者有效?
您可以在基类中声明子类应该具有num
值:
abstract class Base {
val num: Int
}
然后使用第二个变体
val i: List[Base] = List(alpha(4,"test"),beta(2,"test_two")).sortBy(_.num)
您的第一个示例不起作用,因为它没有.num
成员Base
。尽管List
的所有元素可能都有.num
成员,但编译器已被告知将它们视为类型Base
_.num
因此无效。仅当方法num()
存在时,sortWith()
示例才有效。像这样的东西。
def num(x: Base): Int = x match {
case a: alpha => a.num // BTW, class names should be capitalized
case b: beta => b.num
case _ => 0
}
现在,第二个示例可以编译并工作,因为num()
方法正在确定类型并提取.num
成员(如果存在)。但如果是这种情况,那么你的第一个例子也可以工作。
val i: List[Base] = List(alpha(4,"test"),beta(2,"test_two")).sortBy(num)
按照 @Harald 的建议,如果按如下方式修改提供的函数,则sortWith
方法将起作用:
abstract class Base {
val num: Int
}
case class Alpha(num: Int, other: String) extends Base
case class Beta(num: Int, other_two: String) extends Base
List(Alpha(4, "test"), Beta(2, "test_two")).sortWith(_.num < _.num)
res1: List[Product with Serializable with Base] = List(Beta(2,test_two), Alpha(4,test))
// OR
List(Alpha(4, "test"), Beta(2, "test_two")).sortWith((x, y) => x.num < y.num)
res2: List[Product with Serializable with Base] = List(Beta(2,test_two), Alpha(4,test))