2011-05-16 24 views
5

Estoy escribiendo un generador de código Java.Opción Scala [(A, B)] coincidencia de patrón

que tienen un mapa inmutable que contiene un mapeo de java.sql.Types [Int] a una tupla de (String, String) donde el primer valor es un tipo Java y el segundo un paquete de Java desde la que importar el tipo si no se importa de manera predeterminada (java.lang):

val SqlTypesToJavaTypeNames = 
    Map(Types.BIGINT -> ("Long", None), 
     Types.BINARY -> ("byte[]", None), 
     Types.BIT -> ("Boolean", None), 
     Types.BOOLEAN -> ("Boolean", None), 
     Types.CHAR -> ("String", None), 
     Types.DATE -> ("Date", Some("java.sql.Date")), 
     Types.DECIMAL -> ("BigDecimal", Some("java.math.BigDecimal")), 
     Types.DOUBLE -> ("Double", None), 
     Types.FLOAT -> ("Float", None), 
     Types.INTEGER -> ("Integer", None), 
     Types.LONGNVARCHAR -> ("String", None), 
     Types.LONGVARCHAR -> ("String", None), 
     Types.NCHAR -> ("String", None), 
     Types.NUMERIC -> ("BigDecimal", None), 
     Types.NVARCHAR -> ("String", None), 
     Types.REAL -> ("Float", None), 
     Types.SMALLINT -> ("Short", None), 
     Types.SQLXML -> ("String", None), 
     Types.TIME -> ("Time", Some("java.sql.Time")), 
     Types.TIMESTAMP -> ("Timestamp", Some("java.sql.Timestamp")), 
     Types.TINYINT -> ("Byte", None), 
     Types.VARCHAR -> ("String", None)) 

estoy tratando de coincidencia de patrones en una búsqueda de este mapa, donde dataType es el valor java.sql.Types de una base de datos de metadatos:

val (javaType, importType) = 
    SqlTypesToJavaTypeNames.get(dataType) match { 
    case Some(jType, Some(iType)) => (jType, iType) 
    case Some(jType, None) => (jType, null) 
    case None => throw new IllegalStateException("Unknown translation to Java type for SQL type " + dataType) 
    } 

El compilador me está dando un error en el primer case (comienza con case Some(jType, Some(iType))): error: wrong number of arguments for <none>: (x: (java.lang.String, Option[java.lang.String]))Some[(java.lang.String, Option[java.lang.String])]

No estoy seguro de lo que está mal.

+2

Te has perdido los paréntesis. 'Some (x, y)' no es 'Some ((x, y))'. –

+2

Quité el 2.9.0 de la pregunta ya que no es específico de la nueva versión de scala –

Respuesta

11

Some doesn' t extraer a dos valores, se extrae a uno. Si desea hacer coincidir algún par, entonces necesita doblar en el paréntesis:

case Some((jType, Some(iType))) => (jType, iType) 

Sería bueno si pudiera utilizar la convención de flecha como un extractor, pero que lamentablemente no parece funcionar:

case Some(jType -> Some(iType)) => (jType, iType) 

ACTUALIZACIÓN

Por otra parte, dado que está utilizando una Opción, puede aprovechar su naturaleza monádica y simplemente hacer un mapa de la cosa:

val tpes = SqlTypesToJavaTypeNames.get(dataType) 
val (javaType, importType) = 
    tpes map { case (a,b) => (a, b.orNull) } getOrElse { throw ... } 
+0

Puede presumiblemente definir su propio extractor para '->' –

+0

@oxbow_lakes: podría hacerlo, pero en este caso tuve una mejor idea :) –

+0

y entonces, parece, lo hizo :) –

6

Te estas perdiendo los parens interiores (porque tiene un Option[(A, B)]:

case Some((jType, Some(iType))) => 
case Some((jType, _))   => 
case None       => 

Desde el aspecto de su método, parece que se podría simplificar aún más:

SqlTypesToJavaTypeNames.get(dataType) map { case (jType, maybeIType) => jType -> maybeIType.orNull } getOrElse error("Unmapped : " + dataType) 
+3

Una vez más, ¿por qué oh por qué no es 'Option.fold' (o' mapOrElse', o como quieras llamarlo) en la biblioteca estándar? –

Cuestiones relacionadas