2011-05-16 79 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