使用scala提取器作为解析器

时间:2015-07-07 09:09:55

标签: scala

我经常遇到我想要使用提取器作为解析器的情况,它们对此非常有用,但它看起来永远不正常,通常看起来应用程序看起来应该是unapply。此外,解析提取器可能会妨碍默认提取器。这有什么模式吗?

case class AnID(int: Int) extends AnyVal

object AnID {
  def unapply(idString: String): Option[AnID] = "id-([0-9]+)".r match {
    case Seq(intString: String) => Try(Integer.parseInt(intString)).map(AnID.apply).toOption
    case _ => None
  }
}

测试:

AnID(8) should be (AnID(8))
val AnID(id1) = "id-1"
id1 should be (AnID(1))
val AnID(id2) = AnID(2)
id2 should be (2)

有点奇怪。

1 个答案:

答案 0 :(得分:5)

您可以在随播对象中创建一个Parse对象,以便更清楚地表明您正在解析。

case class AnID(int: Int) extends AnyVal
object AnID {
  private val Reg = "id-([0-9]+)".r
  object Parse {
    def unapply(s: String): Option[AnID] = s match {
      case Reg(digits) => Some(new AnID(digits.toInt))
      case _ => None
    }
  }
}

所以现在你至少不要破坏你的正常提取器并且看起来像val AnID.Parse(id) = "id-9"

也许这不会解决你对模式匹配看起来倒退的普遍不安。如果没有,你可以随时让Parse只实现一个apply,然后你得到val Option(x) = AnID.Parse("id-9")