使用scala提取器作为解析器

Mik*_*keB 0 scala

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

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
  }
}
Run Code Online (Sandbox Code Playgroud)

并测试:

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)
Run Code Online (Sandbox Code Playgroud)

这有点奇怪.

Rex*_*err 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
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

所以现在你至少不要破坏你的正常提取器,看看它们的样子val AnID.Parse(id) = "id-9".

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