我有一个基类(让我们把它命名为 Base
)和多个扩展类和方法进行验证。validate
它接受 Any
.
我想检查参数是否是Base的子类,这样我就可以调用 validate
方法,如果它是List of instances of subclass of Base也要这样做。
我试过下面的代码,但这不能编译。有没有一种简单、优雅的方法?
class Base {
def validate(): Unit = {}
}
class Extended1 extends Base {
override def validate(): Unit = {
// some checks
}
}
def validate(param: Any): Unit = {
param match {
case b: Base => b.validate()
// this is not working
case l: List[+Base] => l.foreach(_.validate())
case _ => // do nothing
}
}
UPDATE:我可以使用方法的重载。我还有一些检查,我从问题中删除了,这是错误的,对不起。
那么,我有一个基类(让我们来看看)。
def validate(param: Any): Unit = {
if (Option(param).isEmpty) throwMissingReqFieldException(param)
param match {
case b: Base => b.validate()
case _ =>
}
}
def validate(param: List[Any]): Unit = {
if (Option(param).isEmpty || fieldValue.isEmpty) throwMissingReqFieldException(param)
// here I would like to recursively call validate if possible, maybe this is the solution
param.foreach(x => validate(x))
}
尝试与类型类的方法
trait Validate[T] {
def validate(t: T): Unit
}
object Validate {
implicit def defaultValidate[T]: Validate[T] = _ => ()
implicit val baseValidate: Validate[Base] = _.validate()
implicit def baseListValidate[B <: Base]: Validate[List[B]] = _.foreach(_.validate())
}
def validate[T](param: T)(implicit v: Validate[T]): Unit = v.validate(param)
如果你绝对需要一个 Any
作为参数,这样做。
def validate(param: Any): Unit = {
param match {
case b: Base => b.validate()
case l: List[Base] => if (list.forall(_.isInstanceOf[Base])) l.foreach(_.validate())
case _ => // do nothing
}
}
这里 [Base]
部分实际上是无用的,但它告诉编译器把你的列表当作一个 List[Base]
. 实际的检查是在if语句中,你要确保所有的对象都是 Base
对象。
你也可以做 l.foreach(b => if (b.isInstanceOf[Base]) validate(b))
如果你不在乎列表中不只包含了 Base
的,也可能包含 String
的
不过,更好的办法是超载。
def validate(b: Base): Unit = b.validate()
def validate(l: List[Base]): Unit = l.foreach(validate)