我经常遇到我想要使用提取器作为解析器的情况,它们对此非常有用,但它看起来永远不正常,通常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)
这有点奇怪.
您可以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").