2011-09-23 9 views
16

¿Hay alguna forma de analizar automáticamente un objeto de una cadena, en Scala? ¿Usando alguna función Scala incorporada/generada automáticamente?¿Construido en el análisis de una secuencia a un objeto de caso de Scala?

Por ejemplo, tengo objetos estos casos: (tenga en cuenta que hay una clase padre sellado)

abstract sealed class FlagReason 

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

y me pregunto si hay alguna función generada de forma automática que funciona como:

FlagReason.fromString(value: String): FlagReason

donde FlagReason("Spam") devolvería el objeto de caso Spam.

Si lo hubiera, entonces no necesito escribir mi propia - lo que he hecho:

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

Antecedentes: Estoy convirtiendo mi caso se opone a las cadenas que utilizo como valores de botón de opción en forma de html Estoy convirtiendo el valor seleccionado a un objeto caso, cuando manejo el formulario enviado.

Información relacionada: Esto es realmente posible con las enumeraciones de Java, consulte p. Ej. esta pregunta de StackOverflow: Lookup enum by string value

((No creo que esté buscando los Combinators del Analizador de Scala. Supongo que si los utilizo, igual tendré que definir las reglas de análisis, en lugar de haber incorporado "automática" conversión de objeto de cadena a caja))

+0

Nota, que muestra su enlace C# enumeraciones. Por cierto, ¿puede proporcionar un escenario, donde realmente necesita esa característica? – agilesteel

+0

@agilesteel: he arreglado el enlace ahora, gracias. También agregué algo de información sobre por qué hago ese tipo de conversión. – KajMagnus

Respuesta

25

No, ese método no se genera automáticamente. Deberá escribir su propio método fromString. Tenga en cuenta que se puede escribir de forma más compacta de la siguiente manera:

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

Alternativamente, usted puede considerar el uso de scala.Enumeration la que proporciona este servicio.

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

A continuación, se puede obtener el valor de enumeración particular FlagReason withName "<name>", o con seguridad como una Option con Try(FlagReason withName "<name>").toOption.

+0

Gracias, algo así como 'extends Enumeration' era algo de lo que esperaba :-) – KajMagnus

3

Como missingfaktor señala, FlagReason withName "<name>" debe hacer lo que necesita. Pero si <name> no es un nombre válido, emitirá una excepción. Por lo tanto, de una manera un poco más segura de manejar esto cuando no está seguro de si el nombre es válido es utilizar 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 
Cuestiones relacionadas