2011-05-16 80 views
5

我正在编写Java代码生成器。Scala选项[(A,B)]模式匹配

我有一个不可变的映射,它包含从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))):​​

我不知道什么是错的。

+2

你缺少括号。 'Some(x,y)'不是'Some((x,y))'。 – 2011-05-16 21:02:06

+2

我删除了问题中的2.9.0,因为这不是特定于新版本的scala – 2011-05-16 21:11:43

回答

11

Some没有按”如果你想匹配一对,那么你需要在括号中加倍:

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

这将是很好,如果你可以使用箭头约定作为提取,但可悲的是似乎不工作:

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

UPDATE

或者,因为你使用一个选项,你可以利用它的一元性的,简单地映射在事情:

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

你可能想定义你自己的提取器为' - >' – 2011-05-16 21:13:51

+0

@oxbow_lakes:我可以做,但在这种情况下,我有一个更好的主意:) – 2011-05-16 21:19:51

+0

所以,看起来,你:) – 2011-05-16 21:21:02

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) 
+3

再次,为什么哦为什么不是'Option.fold'(或'mapOrElse',或者其他你想要调用它的东西)标准库? – 2011-05-17 07:16:57