概要として、リフレクションを使用して Cassandra Java 行からケース クラスのコンストラクターを動的に作成し、ケース クラスのプライマリ コンストラクターを見つけてから、Cassandra 行から値を抽出しようとしています。
具体的には、ケース クラスの Option を行のオプション フィールドとしてサポートしたいと考えています。これにより、
case class Person(name: String, age: Option[Int])
行に名前と年齢、または名前だけが含まれている (そして年齢に None を入力する) 場合に正常に入力されます。
この目的のために、Case Classes と Maps の間で同様の目的を達成するこの非常に役立つブログ投稿に従いました。
しかし、Case Class から反射的に型を抽出するという動的な性質と、準引用符のコンパイル時の性質を統合しようとして行き詰まっているようです。例として:
fieldType
ネイティブ型またはネイティブ型のオプションである可能性のある型があります。オプションの場合は、returnType.typeArgs.head
準引用符の作成に渡し、パラメーター化された型を行から抽出できるようにします。オプションでない場合は、returnType だけを渡します。
if (fieldType <:< typeOf[Option[_]])
q"r.getAs[${returnType.typeArgs.head}]($fieldName)"
else
q"r.as[$returnType]($fieldName)"
(r が Cassandra Row でありas
、getAs
この Row に存在すると仮定)
これをコンパイルしようとすると、実行方法がわからないというエラーが表示されますr.as[Option[String]]
。ランタイム比較がどちらの方法で解決されるかをコンパイラーが知る方法がないため、両方のケースをチェックする必要があるため、これは私にとって概念的に理にかなっています。
では、この型チェックを行うにはどうすればよいでしょうか。タイプと準クォート内を比較できれば、文句を言うのをやめるかもしれませんが、準クォート内のタイプを比較する方法がわかりません。それが可能かどうかさえわかりませんfieldType
。typeOf[Option[_]]
quasiquote 内の Option のパラメーター化された型を抽出できれば、文句を言わなくなるかもしれませんが、それもわかりませんでした。
申し訳ありませんが、私は Scala に非常に慣れていないため、現時点では、これは非常に混乱し、難解です。私がやっていることをもっと詳しく見たい場合は、https://github.com/thurstonsand/scala-cass/blob/master/src/main/scala/com/weather/scalacas/ScalaCass というリポジトリがあります。興味深い部分はScalaCass.CaseClassRealizer で、CaseClassUnitTests でテストしています。