我收到以下匹配警告。
" 匹配可能并非详尽无遗。它会在以下输入上失败:一些((x:抽象forSome x不在(A,B,C)))"
代码:
abstract class Abstract
case class A() extends Abstract
case class B() extends Abstract
case class C() extends Abstract
class matcher {
def matcher(a: Option[Abstract]) = a match {
case None => true
case Some(A()) => false
case Some(B()) => false
case Some(C()) => false
}
}
如果你想知道,这里的案例类没有参数,但在我的实际代码中它们没有。我希望答案不是"编译器无法知道程序中某处是否有Abstract
的附加子类...
是否将抽象类封装成唯一的解决方案? scala不是一个非常动态的语言,那么为什么编译器不知道编译警告中提到的组是空组?
答案 0 :(得分:1)
这可能并不理想,但如果您不想封印摘要,它就会起作用。
abstract class Abstract
sealed abstract class SealedAbstract
case class A() extends SealedAbstract
case class B() extends SealedAbstract
case class C() extends SealedAbstract
class matcher {
def matcher(a: Option[Abstract]) = a match {
case None => true
case Some(thing) => matcher(thing)
}
def matcher(a: Abstract) = a match{
case seal: SealedAbstract => matcher(seal)
case _ => false
}
//this will be exhaustive
def matcher(a: SealedAbstract) a match{
case A() => false
case B() => false
case C() => false
}
}
对Abstract对象执行逻辑的更好(且更易于维护/可扩展)的方法是使用类型类。
abstract class Abstract
sealed abstract class SealedAbstract
case class A() extends SealedAbstract
case class B() extends SealedAbstract
case class C() extends SealedAbstract
trait PerformAction[Type <: Abstract]{def doSomething(in: Type): String}
implicit object SealedPerformAction extends PerformAction[SealedAbstract]{
override def doSomething(sa: SealedAbstract): String = "It does."
}
class matcher {
def doIfExists[Type <: Abstract](a: Option[Type])(implicit ev: PerformAction[Type]): String = a match{
case None => ""
case Some(thing) => ev.doSomething(thing)
}
}
使用类型类,您可以获得详尽的模式匹配,并且您可以在库外部获得类型安全性,因为如果库实现了自己的抽象,则库的任何用户都必须实现PerformAction。