作为概述,我尝试使用反射从Cassandra Java Row动态创建案例类的构造函数,以查找案例类的主要构造函数,然后尝试从Cassandra Row中提取值。
具体来说,我想支持案例类中的Option作为Row中的可选字段,这样
case class Person(name: String, age: Option[Int])
如果Row有名称和年龄,或者只是名称(并填写年龄为None),将成功填充。
为此,我遵循this very helpful blog post,在案例类和地图之间实现了类似的目标。
然而,我似乎一直试图巩固从Case Class中反射提取类型的动态特性以及quasiquotes的编译时性质。举个例子:
我有一个类型fieldType
,可以是本机类型,也可以是本机类型的选项。如果它是一个Option,我想将returnType.typeArgs.head
传递给我的quasiquote构造,以便它可以从Row中提取参数化类型,如果它不是Option,我将只传递returnType。
if (fieldType <:< typeOf[Option[_]])
q"r.getAs[${returnType.typeArgs.head}]($fieldName)"
else
q"r.as[$returnType]($fieldName)"
(假设r是Cassandra行,此行存在as
和getAs
当我尝试编译时,我收到一条错误消息,说它不知道如何处理r.as[Option[String]]
。这对我来说具有概念意义,因为编译器无法知道运行时比较将以哪种方式解析,因此需要检查这两种情况。
那我怎么去做这种类型的检查?如果我可以比较quasiquote中的类型fieldType
和typeOf[Option[_]]
,它可能会停止抱怨,但我无法弄清楚如何比较quasiquote中的类型,我不确定它是否均匀可能。如果我可以在quasiquote中提取Option的参数化类型,它可能会停止抱怨,但我也无法解决这个问题。
对不起,我是Scala的新手,而且这件事对我来说非常混乱和深奥。如果你想更仔细地看看我在做什么,我有一个回购:https://github.com/thurstonsand/scala-cass/blob/master/src/main/scala/com/weather/scalacass/ScalaCass.scala 其中有趣的部分是ScalaCass.CaseClassRealizer,我在CaseClassUnitTests中测试它。
答案 0 :(得分:0)
我在gitter scala / scala页面上找到了@liff的帮助。 显然,我发现我的fieldType不正确。
我在做:val fieldType = tpe.decl(encodedName).typeSignature
我应该做val fieldType = field.infoIn(tpe)
。一旦我知道这种差异意味着什么就会更新。