是否可以在类型String上进行模式匹配并获得修剪结果?

时间:2015-06-29 01:28:30

标签: scala pattern-matching

说我有这样的代码:

def isCryptoExample(parts: Seq[Any]): Boolean = parts match {
    case List(loneWord)                      => false
    case List(subject: String, verb: String) =>
      ((subject.trim startsWith "Alice") || (subject.trim startsWith "Bob")) &&
      ((verb.trim == "encrypts") || (verb.trim == "decrypts"))
  }

那些重复的.trim调用很难看,但添加像val subjectTrimmed = subject.trim这样的语句几乎是一种丑陋的解决方法。有没有办法在case语句中立即修剪模式匹配变量?

2 个答案:

答案 0 :(得分:4)

您可以定义自己的Trimmed提取器:

object Trimmed {
  def unapply(s: String): Option[String] = Some(s.trim)
}

然后像这样使用它:

def isCryptoExample(parts: Seq[Any]): Boolean = parts match {
    case List(loneWord)      => false
    case List(Trimmed(subject), Trimmed(verb)) =>
      ((subject startsWith "Alice") || (subject startsWith "Bob")) &&
      ((verb == "encrypts") || (verb == "decrypts"))
  }

Daniel Westheide对提取器及其工作方式有an excellent introduction

答案 1 :(得分:2)

与Emil的另外几个选择:

val Subject = """\s*(Alice|Bob)\s*""".r
val Verb = """\s*(encrypts|decrypts)\s*""".r
List("Alice", "  encrypts  ") match {
  case List(Subject(s), Verb(v)) => true
  case _ => false
}

val ss = List("Alice", "Bob")
val vs = List("encrypts", "decrypts")
List("Alice", "  encrypts  ") match {
  case (List(s, v)) if ss.contains(s.trim) && vs.contains(v.trim) => true
  case _ => false
}