2016-01-12 55 views
0

作爲一個概述,我試圖動態創建一個Cassandra Java Row的案例類的構造函數,使用反射來查找案例類的主要構造函數,然後嘗試從Cassandra Row。scala quasiquotes:比較類型

具體來說,我想支持的情況下類的選項爲在該行的可選字段,這樣 case class Person(name: String, age: Option[Int]) 將成功地填充如果該行有一個名字和年齡,或者只是名稱(和填充年齡無)。

爲此,我跟着this very helpful blog post實現了Case Classes和Maps之間的類似目標。

但是,我似乎被困在試圖鞏固從Case Case中反射提取類型的動態性質和quasiquotes的編譯時性質。作爲一個例子:

我有一個類型fieldType這可能是一個本地類型或本機類型的選項。如果它是一個選項,我想通過returnType.typeArgs.head到我的quasiquote構造,以便它可以從行中提取參數化類型,如果它不是一個選項,我將只傳遞returnType。

if (fieldType <:< typeOf[Option[_]]) q"r.getAs[${returnType.typeArgs.head}]($fieldName)" else q"r.as[$returnType]($fieldName)"

(假設r是一個卡桑德拉行和asgetAs存在此列);

當我嘗試編譯,我得到一個錯誤,指出它不知道如何應對做r.as[Option[String]]。這對我來說具有概念意義,因爲編譯器無法知道運行時比較將以何種方式解決,因此需要檢查兩種情況。

那麼我該如何去做這種類型的檢查?如果我可以在quasiquote中比較類型fieldTypetypeOf[Option[_]],它可能會停止抱怨,但我無法弄清楚如何比較quasiquote中的類型,我不確定這甚至是可能的。如果我可以在quasiquote中提取Option的參數化類型,它可能會停止抱怨,但我無法弄清楚。

對不起,我是斯卡拉的新手,目前這個東西對我來說非常混亂和深奧。如果你想更仔細地看看我在做什麼,我有一個回購:https://github.com/thurstonsand/scala-cass/blob/master/src/main/scala/com/weather/scalacass/ScalaCass.scala 其中有趣的部分是ScalaCass.CaseClassRealizer,我正在CaseClassUnitTests中測試它。

回答

0

我從@liff在gitter scala/scala頁面上找到了幫助。 顯然,我發現我的fieldType不正確。

我在做:val fieldType = tpe.decl(encodedName).typeSignature我應該在那裏做val fieldType = field.infoIn(tpe)。一旦我知道這種差異意味着什麼,將會更新。