2015-07-07 3 views
0

Я продолжаю сталкиваться с ситуациями, когда я хочу использовать экстракторы в качестве синтаксических анализаторов, они действительно полезны для этого, но он никогда не выглядит правдоподобным, часто неприглядное выглядит так, как будто оно должно применяться. Кроме того, экстрактор синтаксического анализа может помешать первому экстрактору. Существуют ли какие-либо шаблоны для этого?Использование экстрактора scala в качестве синтаксического анализатора

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) 

Это какое-то странное.

ответ

4

Вы можете создать объект 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 просто реализовать заявку, а затем получите val Option(x) = AnID.Parse("id-9").

+0

Это то, к чему я склонялся, но мне было необходимо подтверждение. Я хочу использовать unapply, поскольку он позволяет мне сопоставлять некоторые типы ввода и строки синтаксического анализа, которые извлекаются из других структур. Я думаю, что сопоставление образцов - лучший способ сделать это, просто он чувствует, что это работает против конвенции – MikeB

Смежные вопросы