我有一个基类(让我们将其命名为Base)和多个用于验证validate的扩展类和方法,这些类和方法接受Any。
我想检查参数是否是Base的子类,这样我就可以从它调用validate方法,也可以检查它是否是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
}
}更新:我可以使用重写方法。我有更多的检查,我从问题中删除,这是错误的,对不起。
所以:
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))
}发布于 2020-05-20 23:36:07
尝试使用类型类的方法
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)发布于 2020-05-20 23:25:41
如果您绝对需要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对象。
如果您不关心列表不只包含Base,也可以包含String或其他任何内容,您也可以使用l.foreach(b => if (b.isInstanceOf[Base]) validate(b))
不过,更好的方法是重载:
def validate(b: Base): Unit = b.validate()
def validate(l: List[Base]): Unit = l.foreach(validate)https://stackoverflow.com/questions/61916640
复制相似问题