如何公开模式匹配的测试

时间:2010-09-10 23:16:54

标签: scala

我是斯卡拉的新手,但基本上已经找到了解决方法......

在这里,我要求推荐/最佳实践/惯用的方式来实现这个:

  • 在内部,MyClass使用 state 类型,该类型由密封的案例类层次结构实现
  • 但是在API上,只应公开一些布尔谓词,这是通过匹配(内部)状态来实现的。

目前,我的实施方式是......

def isSane: Boolean = state match {
    case Ok(_,'valid) => true
    case _            => false
}

但是这个解决方案对我来说感觉很尴尬,好像在3行代码中表达了一些只有一行代码的信息内容。实际上,我想写的是:

def isSane: boolean = state matches Ok(_, 'valid)

可能/很可能在scala中自己实现一个合适的运算符,但在我研究之前,我想知道解决这个问题的通常方法是什么。也许还有一些现有的库实现?

3 个答案:

答案 0 :(得分:2)

我可能过时了,但为什么不使用多态?

trait State { def sane: Boolean }

trait InvalidState extends State { def sane = false }

case class Ok(whatever: Whatever, s: Symbol) extends State {
   def sane = { s == 'valid }
}

case class Failure(msg: String) extends InvalidState 

case class WarmingUp extends InvalidState

// ...

def isSane(): Boolean = state.sane

当然,如果出于某种原因无法做到这一点,你可以稍微概括Daniel's solution

class Matcher[T](o: T) {
   def matches(pf: PartialFunction[T, Unit]) = pf isDefinedAt o
}

object Matcher {
   implicit def o2matcher[T](o: T): Matcher[T] = new Matcher(o)
}

// then
def isSane = state matches { case Ok(_,'valid) => }

答案 1 :(得分:2)

我会做这样的事情:

abstract class State {
  def matches(pf: PartialFunction[State, Unit]) = pf isDefinedAt this
}

// then

def isSane = state matches { case Ok(_,'valid) => }

由于matches被定义为接收部分函数,​​因此您可以使用函数文字来跟随它,只使用应该导致为true的case语句。您不需要返回任何内容,因为partial函数被定义为返回Unit。最后,matches方法使用部分函数的isDefinedAt方法来验证是否存在覆盖自身的案例陈述。

答案 2 :(得分:1)

如果静态地知道Symbol属性是state类型的属性:

def isSane: Boolean =
  state.secondSymbolPropertyWhateverItsCalled == 'valid

如果您不知道stateOk,那么:

def isSane: Boolean =
  state.isInstanceOf[Ok] && state.asInstanceOf[Ok].symbolProp == 'valid

但是在这一点上,它并没有真正优于你所写的内容。

最后,您可以在该类型的层次结构上定义isSane并委托给它:

def isSane: Boolean =
  state.isSane