我是斯卡拉的新手,但基本上已经找到了解决方法......
在这里,我要求推荐/最佳实践/惯用的方式来实现这个:
目前,我的实施方式是......
def isSane: Boolean = state match {
case Ok(_,'valid) => true
case _ => false
}
但是这个解决方案对我来说感觉很尴尬,好像在3行代码中表达了一些只有一行代码的信息内容。实际上,我想写的是:
def isSane: boolean = state matches Ok(_, 'valid)
可能/很可能在scala中自己实现一个合适的运算符,但在我研究之前,我想知道解决这个问题的通常方法是什么。也许还有一些现有的库实现?
答案 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
如果您不知道state
是Ok
,那么:
def isSane: Boolean =
state.isInstanceOf[Ok] && state.asInstanceOf[Ok].symbolProp == 'valid
但是在这一点上,它并没有真正优于你所写的内容。
最后,您可以在该类型的层次结构上定义isSane
并委托给它:
def isSane: Boolean =
state.isSane