scala quasiquotes:比较类型

scala quasiquotes: comparing types

总的来说,我正在尝试从 Cassandra Java 行动态创建案例 class 的构造函数,使用反射找到案例 class 的主构造函数,然后尝试从 Cassandra 行中提取值。

具体来说,我想在 class 的情况下支持选项作为行中的可选字段,这样 case class Person(name: String, age: Option[Int]) 如果该行有姓名和年龄,或只有姓名(并为年龄填写 None),将成功填充。

为此,我遵循了 this very helpful blog post,在 Case Classes 和 Maps 之间实现了类似的 objective。

但是,我似乎无法尝试巩固从 Case Class 中反射提取类型的动态特性和准引用的编译时特性。例如:

我有一个类型 fieldType,它可以是原生类型或原生类型的 Option。如果它是一个 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 行并且此行存在 asgetAs

当我尝试编译它时,我收到一条错误消息,提示它不知道如何处理 r.as[Option[String]]。这对我来说在概念上很有意义,因为编译器无法知道运行时比较将以哪种方式解决,因此需要检查这两种情况。

那么我该如何进行这种类型检查呢?如果我可以比较准引用中的类型 fieldTypetypeOf[Option[_]],它可能会停止抱怨,但我无法弄清楚如何比较准引用中的类型,而且我不确定它是否均匀可能的。如果我可以在准引用中提取选项的参数化类型,它可能会停止抱怨,但我也无法弄清楚。

抱歉,我是 Scala 的新手,目前,这些东西对我来说非常混乱和深奥。如果您想更仔细地了解我在做什么,我有一个回购协议:https://github.com/thurstonsand/scala-cass/blob/master/src/main/scala/com/weather/scalacass/ScalaCass.scala 有趣的部分是 ScalaCass.CaseClassRealizer,我正在 CaseClassUnitTests.

中测试它

我在 gitter scala/scala 页面上找到@liff 的帮助。 显然,我发现我的 fieldType 不正确。

我在做:val fieldType = tpe.decl(encodedName).typeSignature 我应该做的地方 val fieldType = field.infoIn(tpe)。一旦我知道这种差异意味着什么,就会更新。