Встроенный синтаксический анализ строки в объекте Scala? - PullRequest
18 голосов
/ 23 сентября 2011

Есть ли способ автоматически разобрать объект case из строки в Scala?Используя некоторую встроенную / автоматически сгенерированную функцию Scala?

Например, у меня есть следующие объекты case: ( обратите внимание , что есть запечатанный родительский класс)

abstract sealed class FlagReason

case object Spam extends FlagReason
case object Illegal extends FlagReason
case object CopyrightViolation extends FlagReason
case object Other extends FlagReason

и мне интересно, есть ли какая-то автоматически сгенерированная функция, которая работает следующим образом:

FlagReason.fromString(value: String): FlagReason

, где FlagReason("Spam") вернет * case объект *. 1015 *

Еслибыло, тогда мне не нужно писать свой собственный - что я и сделал:

object FlagReason {
  def fromString(value: String): FlagReason = value match {
    case "Spam" => Spam
    case "Illegal" => Illegal
    case "CopyrightViolation" => CopyrightViolation
    case "Other" => Other
  }
}

Фон : я преобразую мои объекты case в строки, которые я использую в качестве переключателязначения в виде HTML.Я преобразовываю выбранное значение обратно в объект case, когда обрабатываю отправленную форму.

Информация, связанная с данной : Это действительно возможно с перечислениями Java, см., Например, этот вопрос StackOverflow: Поиск перечисления по строковому значению

((Я не думаю, что я ищу комбинаторы синтаксического анализатора Scala. Я полагаю, что если бы я использовал их, мне все равно нужно определить правила синтаксического анализая сам, а не встроил "автоматическую" конвертацию строки в объект case))

Ответы [ 2 ]

28 голосов
/ 23 сентября 2011

Нет, такой метод не генерируется автоматически.Вам нужно будет написать свой собственный метод fromString.Обратите внимание, что вы можете написать его более компактно следующим образом:

object FlagReason {
  def fromString(value: String): Option[FlagReason] = {
    Vector(Spam, Illegal, CopyRightViolation, Other).find(_.toString == value)
  }
}

В качестве альтернативы вы можете рассмотреть возможность использования scala.Enumeration, который предоставляет эту возможность.

object FlagReason extends Enumeration {
  val Spam, Illegal, CopyRightViolation, Other = Value
}

ТогдаВы можете получить конкретное значение перечисления с помощью FlagReason withName "<name>" или безопасно как Option с помощью Try(FlagReason withName "<name>").toOption.

3 голосов
/ 15 апреля 2013

Как указывает отсутствующий фактор , FlagReason withName "<name>" должен делать то, что вам нужно. Но если <name> не является допустимым именем, оно выдаст исключение. Таким образом, немного более безопасный способ справиться с этим, когда вы не уверены в правильности имени, заключается в использовании Option[FlagReason]:

scala> def parse(name: String) = FlagReason.values.find(_.toString == name)
parse: (name: String)Option[FlagReason.Value]

scala> parse("Spam")
res0: Option[FlagReason.Value] = Some(Spam)

scala> parse("NonExisting")
res1: Option[FlagReason.Value] = None
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...