Scala选项[(A,B)]模式匹配

时间:2011-05-16 20:57:46

标签: scala pattern-matching scala-option

我正在编写Java代码生成器。

我有一个不可变的Map,它包含从java.sql.Types [Int]到(String, String)元组的映射,其中第一个值是Java类型,第二个是从中导入类型的Java包如果默认情况下未导入(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))

我正在尝试在搜索此地图时模式匹配,其中dataType是数据库元数据中的java.sql.Types值:

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)
  }

编译器在第一个case上给我一个错误(以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])]

我不确定有什么问题。

2 个答案:

答案 0 :(得分:11)

Some不会提取到两个值,而是提取为一个值。如果你想匹配某些对,那么你需要加倍括号:

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

如果你可以使用箭头约定作为提取器,那将是很好的,但遗憾的是这似乎不起作用:

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

<强>更新

或者,鉴于您正在使用选项,您可以利用其monadic性质并简单地映射该事物:

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

答案 1 :(得分:6)

你错过了内在的阴影(因为你有一个Option[(A, B)]

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

从您的方法看起来,您似乎可以进一步简化:

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