首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >匹配协变表

匹配协变表
EN

Stack Overflow用户
提问于 2020-05-20 23:14:48
回答 2查看 64关注 0票数 0

我有一个基类(让我们将其命名为Base)和多个用于验证validate的扩展类和方法,这些类和方法接受Any

我想检查参数是否是Base的子类,这样我就可以从它调用validate方法,也可以检查它是否是Base的子类的实例列表来执行同样的操作。

我尝试了下面的代码,但这不能编译。有没有一种简单、优雅的方法来做这件事呢?

代码语言:javascript
复制
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
  }
}

更新:我可以使用重写方法。我有更多的检查,我从问题中删除,这是错误的,对不起。

所以:

代码语言:javascript
复制
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))
}
EN

回答 2

Stack Overflow用户

发布于 2020-05-20 23:36:07

尝试使用类型类的方法

代码语言:javascript
复制
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)
票数 3
EN

Stack Overflow用户

发布于 2020-05-20 23:25:41

如果您绝对需要Any作为参数,请执行以下操作:

代码语言:javascript
复制
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))

不过,更好的方法是重载:

代码语言:javascript
复制
def validate(b: Base): Unit = b.validate()
def validate(l: List[Base]): Unit = l.foreach(validate)
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61916640

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档