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 行并且此行存在 as
和 getAs
)
当我尝试编译它时,我收到一条错误消息,提示它不知道如何处理 r.as[Option[String]]
。这对我来说在概念上很有意义,因为编译器无法知道运行时比较将以哪种方式解决,因此需要检查这两种情况。
那么我该如何进行这种类型检查呢?如果我可以比较准引用中的类型 fieldType
和 typeOf[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)
。一旦我知道这种差异意味着什么,就会更新。
总的来说,我正在尝试从 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 行并且此行存在 as
和 getAs
)
当我尝试编译它时,我收到一条错误消息,提示它不知道如何处理 r.as[Option[String]]
。这对我来说在概念上很有意义,因为编译器无法知道运行时比较将以哪种方式解决,因此需要检查这两种情况。
那么我该如何进行这种类型检查呢?如果我可以比较准引用中的类型 fieldType
和 typeOf[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)
。一旦我知道这种差异意味着什么,就会更新。