ブラックボックスマクロからfor yield
ブロックを放出しようとすると、私はあなたが有効な構文でブロックを作成することができます方法を理解するために失敗してるから内包のために発行してください。このブロックは後でマッチングPARAM名を有することになるメソッド内に挿入されるようにsource
以下Scalaのマクロ:マクロ
は、ハードコードPARAM名です。 params
はcase class
フィールドを囲む、ちょうどparams: Seq[c.universe.ValDef]
です。
def extract(source: Source): Option[CaseClass] = { ... }
val extractors = accessors(c)(params) map {
case (nm, tpe) => {
val newTerm = TermName(nm.toString + "Opt")
q"""$newTerm <- DoStuff[$tpe].apply("$nm", source)"""
}
}
val extractorNames = accessors(c)(params) map {
case (nm, tpe) => TermName(nm.toString + "Opt")
}
これは、基本的case class
を取って、基本的理解からケースクラスを再作成するための収量ブラックを出力しています。
name: Type
という形式のケースクラスのすべてのフィールドは、for comprehensionが成功した場合、同じcaseクラスインスタンスを返す抽出器のセットに変換されます。
for {
idOpt <- Extract[Int].apply("id", source): Option[Int]
textOpt <- Extract[String].apply("text", source): Option[String]
} yield Test(idOpt, textOpt)
問題がための内部を引用することにしてい:
case class Test(id: Int, text: String)
はExtract
がちょうど型クラスであるとExtract.apply[T : Extract]
だけでimplicitly[Extract[T]]
が結合したコンテキストをマテリアライズされた場合、次のようにマクロ変換されます式を出力し、ブロックa <- b
を出力します。
def extract(source: Source): Option[$typeName] = {
for {(..$extractors)} yield $companion.apply(..$extractorNames)
}
エラーが自身でScalaの無効でかなり明白a <- b
ようである、';' expected but '<-' found
です。上記のように表現ブロックを生成し準直交化する正しい方法は何ですか?
うん、これは一つであり、その間にそれを見つけました。どうもありがとう! – flavian
'{}'ラッパーを追加するのを忘れましたが、コンパイラーはそれらを好きではありません。 '()'で十分です。将来誰かがこの答えに来るように修正するだけです。 – flavian