我经常遇到我想要使用提取器作为解析器的情况,它们对此非常有用,但它看起来永远不正常,通常看起来应用程序看起来应该是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)
有点奇怪。
答案 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")
。