ケースクラス値を受け取り、指定された位置でケースクラスパラメータの値を返す関数に対してTree
を生成しようとしています。これはプライベートパラメータの値を抽出するのに便利です。文字列を補間する前にクォーコットに挿入する
import reflect.runtime.currentMirror
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
val tb = currentMirror.mkToolBox()
case class A(private val first: Int)
case class B(first: Int, private val second: Int)
def get(tpe: Type, position: Option[Int]): Tree = {
val pos = s"${position.map(p => s"._${p + 1}").getOrElse("")}"
tb.parse(s"(a: $tpe) => $tpe.unapply(a).get$pos")
}
println(tb.eval(get(typeOf[A], None)).asInstanceOf[(A) => Int](A(1)))
println(tb.eval(get(typeOf[B], Some(1))).asInstanceOf[(B) => Int](B(1, 2)))
はまた、私は次の依存関係を追加しました:ケースクラスはパラメータを1つしか持っていたときに
scalaVersion := "2.11.8"
libraryDependencies ++= Seq(
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
"org.scala-lang" % "scala-compiler" % scalaVersion.value
)
position
はNone
です。
私の解決策は動作していますが、どうすればtb.parse(s"...")
とをquasiquoteq"..."
に置き換えることができますか?
私はそれを試してみましたが、それはで失敗します。私は、実行時に構築されていますし、q"..."
がtb.parse
とは異なり、コンパイル時に解析される準クォートいくつかの文字列に挿入することはできません理解できるように
Don't know how to unquote here
[error] q"(a: $tpe) => $tpe.unapply(a).get$pos"
[error] ^
。 私はそうですか?
また、このような補間は安全ですかs"(a: $tpe) => $tpe.unapply(a).get$pos"
? q"..."
構文を使用するとき、quasiquoteは$tpe
がType
であることを知っていますが、文字列補間は文字列を作成します。私はこれが常により複雑で具体的な場合にはうまくいくとは確信していません。
私は「選択」を忘れました。それに関する詳細な文書はありますか? – mixel
http://scala-lang.org/api/current/scala-reflect 'Select'は' x.y'の '.'です。 – HTNW