Неявное преобразование к перечислениям

Захотелось мне ужасного: сделать неявное преобразование из строки к перечислению в Scala. Почему ужасного? Да потому что чем больше неявных преобразований в реальном, большом проекте, тем тяжелее понять что же происходит на самом деле без отладчика. А отладчик, мало того что доступен далеко не всегда и если есть возможность обойтись без него, то она явно предпочтительнее. Но это все философия, далеко не все будут с ней согласны.

Есть список частей речи в виде перечисления. При парсинге, части речи приходят в виде строки и должн быть преобразованы к перечислению, например “сущ.” -> Acronym.noun.


В принципе, не пиши я приложение на Scala и не будь моей основной целью разобраться с этой самой Scala получше, я бы просто написал внешнюю функцию вида def stringToAcronym(name: String) : Acronym и все. А тут, с учетом цели, я задумался на тему, как мне сделать следующее:

object Acronym extends Enumeration {
  type Acronym = Value
  val noun = Value("noun")
  val verb = Value("verb")
...
  val non = Value("non")
}

...
def foo(acr: Acronym) { // ?????
  println(acr)
}

foo("сущ.")

Насколько я помнил из книги Programming Scala за авторством Dean Wampler и Alex Payne, в Scala есть такая замечательная штука, как неявные преобразования, что добавляло уверенности в вопросе возможности написания такого кода. Как оказалось, все действительно просто. Для обеспечения возможности подобного преобразования достаточно добавить одну функцию в объект Acronym.

implicit def stringToAcronym(acronym: String) : Acronym = {
  println(acronym)
  acronym match {
    case "сущ." | "сущ.мн." => noun
    case "гл." => verb
    case _ => non
  }
}

Да, кстати, очень рекомендую книгу “Programming Scala” – она лучшее из того что есть по Scala на данный момент.

Leave a Reply