【问题标题】:scala quasiquotes: comparing typesscala quasiquotes:比较类型
【发布时间】:2016-01-12 23:07:15
【问题描述】:

作为概述,我尝试使用反射从 Cassandra Java Row 动态创建案例类的构造函数,以找到案例类的主构造函数,然后尝试从 Cassandra Row 中提取值。

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

为此,我关注了this very helpful blog post,它实现了案例类和地图之间的类似目标。

但是,我似乎被困在试图巩固从案例类中反射性地提取类型的动态特性和准引号的编译时特性。举个例子:

我有一个 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[_]] 类型,它可能会停止抱怨,但我不知道如何比较准引用中的类型,我什至不确定它是否可能。如果我可以在准引号中提取 Option 的参数化类型,它可能会停止抱怨,但我也无法弄清楚。

抱歉,我对 Scala 还很陌生,目前这些东西对我来说非常混乱和深奥。如果你想更仔细地看看我在做什么,我有一个回购:https://github.com/thurstonsand/scala-cass/blob/master/src/main/scala/com/weather/scalacass/ScalaCass.scala 其中有趣的部分是 ScalaCass.CaseClassRealizer,我正在 CaseClassUnitTests 中对其进行测试。

【问题讨论】:

    标签: scala scala-macros scala-quasiquotes


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      • 2010-11-03
      相关资源
      最近更新 更多